diff options
author | Christian Grothoff <christian@grothoff.org> | 2022-01-15 19:24:33 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2022-02-19 12:39:55 +0100 |
commit | b0abdf7127f2403ff583d224e0d9d4e68c1c5bfc (patch) | |
tree | 47df762cdbcce501ec5536c8963b5c9ee55da31d /src/dht | |
parent | 3a71153405e8fc26712807b4bdb5987fb3bf2b9e (diff) | |
download | gnunet-b0abdf7127f2403ff583d224e0d9d4e68c1c5bfc.tar.gz gnunet-b0abdf7127f2403ff583d224e0d9d4e68c1c5bfc.zip |
-more work on DHTU integration
Diffstat (limited to 'src/dht')
-rw-r--r-- | src/dht/Makefile.am | 1 | ||||
-rw-r--r-- | src/dht/dht_api.c | 11 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht.c | 149 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht.h | 60 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_clients.c | 2 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_datacache.c | 124 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_datacache.h | 11 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_hello.c | 154 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_hello.h | 55 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_neighbours.c | 1108 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_neighbours.h | 17 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_routing.c | 2 |
12 files changed, 814 insertions, 880 deletions
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am index 44439f66f..ab4ec1b3c 100644 --- a/src/dht/Makefile.am +++ b/src/dht/Makefile.am | |||
@@ -58,7 +58,6 @@ noinst_PROGRAMS = \ | |||
58 | gnunet_service_dht_SOURCES = \ | 58 | gnunet_service_dht_SOURCES = \ |
59 | gnunet-service-dht.c gnunet-service-dht.h \ | 59 | gnunet-service-dht.c gnunet-service-dht.h \ |
60 | gnunet-service-dht_datacache.c gnunet-service-dht_datacache.h \ | 60 | gnunet-service-dht_datacache.c gnunet-service-dht_datacache.h \ |
61 | gnunet-service-dht_hello.c gnunet-service-dht_hello.h \ | ||
62 | gnunet-service-dht_neighbours.c gnunet-service-dht_neighbours.h \ | 61 | gnunet-service-dht_neighbours.c gnunet-service-dht_neighbours.h \ |
63 | gnunet-service-dht_routing.c gnunet-service-dht_routing.h | 62 | gnunet-service-dht_routing.c gnunet-service-dht_routing.h |
64 | gnunet_service_dht_LDADD = \ | 63 | gnunet_service_dht_LDADD = \ |
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c index 8389bbb95..a0c30d5e7 100644 --- a/src/dht/dht_api.c +++ b/src/dht/dht_api.c | |||
@@ -726,6 +726,7 @@ process_client_result (void *cls, | |||
726 | const struct GNUNET_DHT_ClientResultMessage *crm = cls; | 726 | const struct GNUNET_DHT_ClientResultMessage *crm = cls; |
727 | struct GNUNET_DHT_GetHandle *get_handle = value; | 727 | struct GNUNET_DHT_GetHandle *get_handle = value; |
728 | size_t msize = ntohs (crm->header.size) - sizeof(*crm); | 728 | size_t msize = ntohs (crm->header.size) - sizeof(*crm); |
729 | uint16_t type = ntohl (crm->type); | ||
729 | uint32_t put_path_length = ntohl (crm->put_path_length); | 730 | uint32_t put_path_length = ntohl (crm->put_path_length); |
730 | uint32_t get_path_length = ntohl (crm->get_path_length); | 731 | uint32_t get_path_length = ntohl (crm->get_path_length); |
731 | const struct GNUNET_DHT_PathElement *put_path; | 732 | const struct GNUNET_DHT_PathElement *put_path; |
@@ -745,7 +746,13 @@ process_client_result (void *cls, | |||
745 | (unsigned long long) get_handle->unique_id); | 746 | (unsigned long long) get_handle->unique_id); |
746 | return GNUNET_YES; | 747 | return GNUNET_YES; |
747 | } | 748 | } |
748 | /* FIXME: might want to check that type matches */ | 749 | if ( (get_handle->type != GNUNET_BLOCK_TYPE_ANY) && |
750 | (get_handle->type != type) ) | ||
751 | { | ||
752 | /* type mismatch */ | ||
753 | GNUNET_break (0); | ||
754 | return GNUNET_YES; | ||
755 | } | ||
749 | meta_length = | 756 | meta_length = |
750 | sizeof(struct GNUNET_DHT_PathElement) * (get_path_length + put_path_length); | 757 | sizeof(struct GNUNET_DHT_PathElement) * (get_path_length + put_path_length); |
751 | data_length = msize - meta_length; | 758 | data_length = msize - meta_length; |
@@ -786,7 +793,7 @@ process_client_result (void *cls, | |||
786 | get_path_length, | 793 | get_path_length, |
787 | put_path, | 794 | put_path, |
788 | put_path_length, | 795 | put_path_length, |
789 | ntohl (crm->type), | 796 | type, |
790 | data_length, | 797 | data_length, |
791 | data); | 798 | data); |
792 | return GNUNET_YES; | 799 | return GNUNET_YES; |
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c index 6f2573d26..35e219926 100644 --- a/src/dht/gnunet-service-dht.c +++ b/src/dht/gnunet-service-dht.c | |||
@@ -28,14 +28,20 @@ | |||
28 | #include "gnunet_block_lib.h" | 28 | #include "gnunet_block_lib.h" |
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
30 | #include "gnunet_hello_lib.h" | 30 | #include "gnunet_hello_lib.h" |
31 | #include "gnunet_hello_uri_lib.h" | ||
31 | #include "gnunet_dht_service.h" | 32 | #include "gnunet_dht_service.h" |
32 | #include "gnunet_statistics_service.h" | 33 | #include "gnunet_statistics_service.h" |
33 | #include "gnunet-service-dht.h" | 34 | #include "gnunet-service-dht.h" |
34 | #include "gnunet-service-dht_datacache.h" | 35 | #include "gnunet-service-dht_datacache.h" |
35 | #include "gnunet-service-dht_hello.h" | ||
36 | #include "gnunet-service-dht_neighbours.h" | 36 | #include "gnunet-service-dht_neighbours.h" |
37 | #include "gnunet-service-dht_routing.h" | 37 | #include "gnunet-service-dht_routing.h" |
38 | 38 | ||
39 | /** | ||
40 | * How often do we broadcast our HELLO to neighbours if | ||
41 | * nothing special happens? | ||
42 | */ | ||
43 | #define HELLO_FREQUENCY GNUNET_TIME_UNIT_HOURS | ||
44 | |||
39 | 45 | ||
40 | /** | 46 | /** |
41 | * Information we keep per underlay. | 47 | * Information we keep per underlay. |
@@ -110,7 +116,27 @@ struct MyAddress | |||
110 | /** | 116 | /** |
111 | * Our HELLO | 117 | * Our HELLO |
112 | */ | 118 | */ |
113 | struct GNUNET_MessageHeader *GDS_my_hello; | 119 | struct GNUNET_HELLO_Builder *GDS_my_hello; |
120 | |||
121 | /** | ||
122 | * Identity of this peer. | ||
123 | */ | ||
124 | struct GNUNET_PeerIdentity GDS_my_identity; | ||
125 | |||
126 | /** | ||
127 | * Hash of the identity of this peer. | ||
128 | */ | ||
129 | struct GNUNET_HashCode GDS_my_identity_hash; | ||
130 | |||
131 | /** | ||
132 | * Our private key. | ||
133 | */ | ||
134 | struct GNUNET_CRYPTO_EddsaPrivateKey GDS_my_private_key; | ||
135 | |||
136 | /** | ||
137 | * Task broadcasting our HELLO. | ||
138 | */ | ||
139 | static struct GNUNET_SCHEDULER_Task *hello_task; | ||
114 | 140 | ||
115 | /** | 141 | /** |
116 | * Handles for the DHT underlays. | 142 | * Handles for the DHT underlays. |
@@ -133,11 +159,6 @@ static struct MyAddress *a_head; | |||
133 | static struct MyAddress *a_tail; | 159 | static struct MyAddress *a_tail; |
134 | 160 | ||
135 | /** | 161 | /** |
136 | * Hello address expiration | ||
137 | */ | ||
138 | struct GNUNET_TIME_Relative hello_expiration; | ||
139 | |||
140 | /** | ||
141 | * log of the current network size estimate, used as the point where | 162 | * log of the current network size estimate, used as the point where |
142 | * we switch between random and deterministic routing. | 163 | * we switch between random and deterministic routing. |
143 | */ | 164 | */ |
@@ -195,13 +216,29 @@ GDS_NSE_get (void) | |||
195 | 216 | ||
196 | 217 | ||
197 | /** | 218 | /** |
198 | * Update our HELLO with all of our our addresses. | 219 | * Task run periodically to broadcast our HELLO. |
220 | * | ||
221 | * @param cls NULL | ||
199 | */ | 222 | */ |
200 | static void | 223 | static void |
201 | update_hello (void) | 224 | broadcast_hello (void *cls) |
202 | { | 225 | { |
203 | GNUNET_free (GDS_my_hello); | 226 | struct GNUNET_MessageHeader *hello; |
204 | // FIXME: build new HELLO properly! | 227 | |
228 | (void) cls; | ||
229 | /* TODO: randomize! */ | ||
230 | hello_task = GNUNET_SCHEDULER_add_delayed (HELLO_FREQUENCY, | ||
231 | &broadcast_hello, | ||
232 | NULL); | ||
233 | hello = GNUNET_HELLO_builder_to_dht_hello_msg (GDS_my_hello, | ||
234 | &GDS_my_private_key); | ||
235 | if (NULL == hello) | ||
236 | { | ||
237 | GNUNET_break (0); | ||
238 | return; | ||
239 | } | ||
240 | GDS_NEIGHBOURS_broadcast (hello); | ||
241 | GNUNET_free (hello); | ||
205 | } | 242 | } |
206 | 243 | ||
207 | 244 | ||
@@ -231,7 +268,12 @@ u_address_add (void *cls, | |||
231 | a_tail, | 268 | a_tail, |
232 | a); | 269 | a); |
233 | *ctx = a; | 270 | *ctx = a; |
234 | update_hello (); | 271 | GNUNET_HELLO_builder_add_address (GDS_my_hello, |
272 | address); | ||
273 | if (NULL != hello_task) | ||
274 | GNUNET_SCHEDULER_cancel (hello_task); | ||
275 | hello_task = GNUNET_SCHEDULER_add_now (&broadcast_hello, | ||
276 | NULL); | ||
235 | } | 277 | } |
236 | 278 | ||
237 | 279 | ||
@@ -245,12 +287,47 @@ u_address_del (void *ctx) | |||
245 | { | 287 | { |
246 | struct MyAddress *a = ctx; | 288 | struct MyAddress *a = ctx; |
247 | 289 | ||
290 | GNUNET_HELLO_builder_del_address (GDS_my_hello, | ||
291 | a->url); | ||
248 | GNUNET_CONTAINER_DLL_remove (a_head, | 292 | GNUNET_CONTAINER_DLL_remove (a_head, |
249 | a_tail, | 293 | a_tail, |
250 | a); | 294 | a); |
251 | GNUNET_free (a->url); | 295 | GNUNET_free (a->url); |
252 | GNUNET_free (a); | 296 | GNUNET_free (a); |
253 | update_hello (); | 297 | if (NULL != hello_task) |
298 | GNUNET_SCHEDULER_cancel (hello_task); | ||
299 | hello_task = GNUNET_SCHEDULER_add_now (&broadcast_hello, | ||
300 | NULL); | ||
301 | } | ||
302 | |||
303 | |||
304 | void | ||
305 | GDS_u_try_connect (const struct GNUNET_PeerIdentity *pid, | ||
306 | const char *address) | ||
307 | { | ||
308 | for (struct Underlay *u = u_head; | ||
309 | NULL != u; | ||
310 | u = u->next) | ||
311 | u->dhtu->try_connect (u->dhtu->cls, | ||
312 | pid, | ||
313 | address); | ||
314 | } | ||
315 | |||
316 | |||
317 | void | ||
318 | GDS_u_send (struct Underlay *u, | ||
319 | struct GNUNET_DHTU_Target *target, | ||
320 | const void *msg, | ||
321 | size_t msg_size, | ||
322 | GNUNET_SCHEDULER_TaskCallback finished_cb, | ||
323 | void *finished_cb_cls) | ||
324 | { | ||
325 | u->dhtu->send (u->dhtu->cls, | ||
326 | target, | ||
327 | msg, | ||
328 | msg_size, | ||
329 | finished_cb, | ||
330 | finished_cb_cls); | ||
254 | } | 331 | } |
255 | 332 | ||
256 | 333 | ||
@@ -265,7 +342,6 @@ shutdown_task (void *cls) | |||
265 | GDS_NEIGHBOURS_done (); | 342 | GDS_NEIGHBOURS_done (); |
266 | GDS_DATACACHE_done (); | 343 | GDS_DATACACHE_done (); |
267 | GDS_ROUTING_done (); | 344 | GDS_ROUTING_done (); |
268 | GDS_HELLO_done (); | ||
269 | if (NULL != GDS_block_context) | 345 | if (NULL != GDS_block_context) |
270 | { | 346 | { |
271 | GNUNET_BLOCK_context_destroy (GDS_block_context); | 347 | GNUNET_BLOCK_context_destroy (GDS_block_context); |
@@ -277,7 +353,7 @@ shutdown_task (void *cls) | |||
277 | GNUNET_YES); | 353 | GNUNET_YES); |
278 | GDS_stats = NULL; | 354 | GDS_stats = NULL; |
279 | } | 355 | } |
280 | GNUNET_free (GDS_my_hello); | 356 | GNUNET_HELLO_builder_free (GDS_my_hello); |
281 | GDS_my_hello = NULL; | 357 | GDS_my_hello = NULL; |
282 | GDS_CLIENTS_stop (); | 358 | GDS_CLIENTS_stop (); |
283 | } | 359 | } |
@@ -348,14 +424,39 @@ run (void *cls, | |||
348 | { | 424 | { |
349 | GDS_cfg = c; | 425 | GDS_cfg = c; |
350 | GDS_service = service; | 426 | GDS_service = service; |
351 | if (GNUNET_OK != | ||
352 | GNUNET_CONFIGURATION_get_value_time (c, | ||
353 | "transport", | ||
354 | "HELLO_EXPIRATION", | ||
355 | &hello_expiration)) | ||
356 | { | 427 | { |
357 | hello_expiration = GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION; | 428 | char *keyfile; |
429 | |||
430 | if (GNUNET_OK != | ||
431 | GNUNET_CONFIGURATION_get_value_filename (GDS_cfg, | ||
432 | "PEER", | ||
433 | "PRIVATE_KEY", | ||
434 | &keyfile)) | ||
435 | { | ||
436 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, | ||
437 | "PEER", | ||
438 | "PRIVATE_KEY"); | ||
439 | GNUNET_SCHEDULER_shutdown (); | ||
440 | return; | ||
441 | } | ||
442 | if (GNUNET_SYSERR == | ||
443 | GNUNET_CRYPTO_eddsa_key_from_file (keyfile, | ||
444 | GNUNET_YES, | ||
445 | &GDS_my_private_key)) | ||
446 | { | ||
447 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
448 | "Failed to setup peer's private key\n"); | ||
449 | GNUNET_free (keyfile); | ||
450 | GNUNET_SCHEDULER_shutdown (); | ||
451 | return; | ||
452 | } | ||
453 | GNUNET_free (keyfile); | ||
358 | } | 454 | } |
455 | GNUNET_CRYPTO_eddsa_key_get_public (&GDS_my_private_key, | ||
456 | &GDS_my_identity.public_key); | ||
457 | GNUNET_CRYPTO_hash (&GDS_my_identity, | ||
458 | sizeof(struct GNUNET_PeerIdentity), | ||
459 | &GDS_my_identity_hash); | ||
359 | GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg); | 460 | GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg); |
360 | GDS_stats = GNUNET_STATISTICS_create ("dht", | 461 | GDS_stats = GNUNET_STATISTICS_create ("dht", |
361 | GDS_cfg); | 462 | GDS_cfg); |
@@ -364,6 +465,12 @@ run (void *cls, | |||
364 | GDS_DATACACHE_init (); | 465 | GDS_DATACACHE_init (); |
365 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, | 466 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, |
366 | NULL); | 467 | NULL); |
468 | if (GNUNET_OK != | ||
469 | GDS_NEIGHBOURS_init ()) | ||
470 | { | ||
471 | GNUNET_SCHEDULER_shutdown (); | ||
472 | return; | ||
473 | } | ||
367 | GNUNET_CONFIGURATION_iterate_sections (GDS_cfg, | 474 | GNUNET_CONFIGURATION_iterate_sections (GDS_cfg, |
368 | &load_underlay, | 475 | &load_underlay, |
369 | NULL); | 476 | NULL); |
diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h index 687e2d4d3..403b3f5a1 100644 --- a/src/dht/gnunet-service-dht.h +++ b/src/dht/gnunet-service-dht.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #define GNUNET_SERVICE_DHT_H | 27 | #define GNUNET_SERVICE_DHT_H |
28 | 28 | ||
29 | #include "gnunet-service-dht_datacache.h" | 29 | #include "gnunet-service-dht_datacache.h" |
30 | #include "gnunet-service-dht_neighbours.h" | ||
30 | #include "gnunet_statistics_service.h" | 31 | #include "gnunet_statistics_service.h" |
31 | #include "gnunet_transport_service.h" | 32 | #include "gnunet_transport_service.h" |
32 | 33 | ||
@@ -34,6 +35,11 @@ | |||
34 | #define DEBUG_DHT GNUNET_EXTRA_LOGGING | 35 | #define DEBUG_DHT GNUNET_EXTRA_LOGGING |
35 | 36 | ||
36 | /** | 37 | /** |
38 | * Information we keep per underlay. | ||
39 | */ | ||
40 | struct Underlay; | ||
41 | |||
42 | /** | ||
37 | * Configuration we use. | 43 | * Configuration we use. |
38 | */ | 44 | */ |
39 | extern const struct GNUNET_CONFIGURATION_Handle *GDS_cfg; | 45 | extern const struct GNUNET_CONFIGURATION_Handle *GDS_cfg; |
@@ -54,9 +60,59 @@ extern struct GNUNET_BLOCK_Context *GDS_block_context; | |||
54 | extern struct GNUNET_STATISTICS_Handle *GDS_stats; | 60 | extern struct GNUNET_STATISTICS_Handle *GDS_stats; |
55 | 61 | ||
56 | /** | 62 | /** |
57 | * Our HELLO | 63 | * Our HELLO builder. |
64 | */ | ||
65 | extern struct GNUNET_HELLO_Builder *GDS_my_hello; | ||
66 | |||
67 | /** | ||
68 | * Identity of this peer. | ||
69 | */ | ||
70 | extern struct GNUNET_PeerIdentity GDS_my_identity; | ||
71 | |||
72 | /** | ||
73 | * Hash of the identity of this peer. | ||
74 | */ | ||
75 | extern struct GNUNET_HashCode GDS_my_identity_hash; | ||
76 | |||
77 | /** | ||
78 | * Our private key. | ||
58 | */ | 79 | */ |
59 | extern struct GNUNET_MessageHeader *GDS_my_hello; | 80 | extern struct GNUNET_CRYPTO_EddsaPrivateKey GDS_my_private_key; |
81 | |||
82 | |||
83 | /** | ||
84 | * Ask all underlays to connect to peer @a pid at @a address. | ||
85 | * | ||
86 | * @param pid identity of the peer we would connect to | ||
87 | * @param address an address of @a pid | ||
88 | */ | ||
89 | void | ||
90 | GDS_u_try_connect (const struct GNUNET_PeerIdentity *pid, | ||
91 | const char *address); | ||
92 | |||
93 | |||
94 | /** | ||
95 | * Send message to some other participant over the network. Note that | ||
96 | * sending is not guaranteeing that the other peer actually received the | ||
97 | * message. For any given @a target, the DHT must wait for the @a | ||
98 | * finished_cb to be called before calling send() again. | ||
99 | * | ||
100 | * @param u underlay to use for transmission | ||
101 | * @param target receiver identification | ||
102 | * @param msg message | ||
103 | * @param msg_size number of bytes in @a msg | ||
104 | * @param finished_cb function called once transmission is done | ||
105 | * (not called if @a target disconnects, then only the | ||
106 | * disconnect_cb is called). | ||
107 | * @param finished_cb_cls closure for @a finished_cb | ||
108 | */ | ||
109 | void | ||
110 | GDS_u_send (struct Underlay *u, | ||
111 | struct GNUNET_DHTU_Target *target, | ||
112 | const void *msg, | ||
113 | size_t msg_size, | ||
114 | GNUNET_SCHEDULER_TaskCallback finished_cb, | ||
115 | void *finished_cb_cls); | ||
60 | 116 | ||
61 | 117 | ||
62 | /** | 118 | /** |
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c index a1c3024de..bc39e004a 100644 --- a/src/dht/gnunet-service-dht_clients.c +++ b/src/dht/gnunet-service-dht_clients.c | |||
@@ -917,7 +917,7 @@ forward_reply (void *cls, | |||
917 | GNUNET_NO); | 917 | GNUNET_NO); |
918 | return GNUNET_YES; /* type mismatch */ | 918 | return GNUNET_YES; /* type mismatch */ |
919 | } | 919 | } |
920 | if ( (0 == (record->msg_options & GNUNET_DHT_RO_FIND_PEER)) && | 920 | if ( (0 == (record->msg_options & GNUNET_DHT_RO_FIND_APPROXIMATE)) && |
921 | (0 != GNUNET_memcmp (&frc->bd->key, | 921 | (0 != GNUNET_memcmp (&frc->bd->key, |
922 | query_hash)) ) | 922 | query_hash)) ) |
923 | { | 923 | { |
diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c index cb778717b..880c72cb2 100644 --- a/src/dht/gnunet-service-dht_datacache.c +++ b/src/dht/gnunet-service-dht_datacache.c | |||
@@ -68,7 +68,7 @@ GDS_DATACACHE_handle_put (const struct GDS_DATACACHE_BlockData *bd) | |||
68 | 1, | 68 | 1, |
69 | GNUNET_NO); | 69 | GNUNET_NO); |
70 | GNUNET_CRYPTO_hash_xor (&bd->key, | 70 | GNUNET_CRYPTO_hash_xor (&bd->key, |
71 | &my_identity_hash, | 71 | &GDS_my_identity_hash, |
72 | &xor); | 72 | &xor); |
73 | r = GNUNET_DATACACHE_put (datacache, | 73 | r = GNUNET_DATACACHE_put (datacache, |
74 | &bd->key, | 74 | &bd->key, |
@@ -231,7 +231,15 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
231 | GDS_DATACACHE_GetCallback gc, | 231 | GDS_DATACACHE_GetCallback gc, |
232 | void *gc_cls) | 232 | void *gc_cls) |
233 | { | 233 | { |
234 | struct GetRequestContext ctx; | 234 | struct GetRequestContext ctx = { |
235 | .eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID, | ||
236 | .key = *key, | ||
237 | .xquery = xquery, | ||
238 | .xquery_size = xquery_size, | ||
239 | .bg = bg, | ||
240 | .gc = gc, | ||
241 | .gc_cls = gc_cls | ||
242 | }; | ||
235 | unsigned int r; | 243 | unsigned int r; |
236 | 244 | ||
237 | if (NULL == datacache) | 245 | if (NULL == datacache) |
@@ -240,13 +248,6 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
240 | "# GET requests given to datacache", | 248 | "# GET requests given to datacache", |
241 | 1, | 249 | 1, |
242 | GNUNET_NO); | 250 | GNUNET_NO); |
243 | ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
244 | ctx.key = *key; | ||
245 | ctx.xquery = xquery; | ||
246 | ctx.xquery_size = xquery_size; | ||
247 | ctx.bg = bg; | ||
248 | ctx.gc = gc; | ||
249 | ctx.gc_cls = gc_cls; | ||
250 | r = GNUNET_DATACACHE_get (datacache, | 251 | r = GNUNET_DATACACHE_get (datacache, |
251 | key, | 252 | key, |
252 | type, | 253 | type, |
@@ -261,85 +262,44 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
261 | } | 262 | } |
262 | 263 | ||
263 | 264 | ||
264 | /** | 265 | enum GNUNET_BLOCK_EvaluationResult |
265 | * Closure for #datacache_get_successors_iterator(). | ||
266 | */ | ||
267 | struct SuccContext | ||
268 | { | ||
269 | /** | ||
270 | * Function to call on the result | ||
271 | */ | ||
272 | GDS_DATACACHE_GetCallback cb; | ||
273 | |||
274 | /** | ||
275 | * Closure for @e cb. | ||
276 | */ | ||
277 | void *cb_cls; | ||
278 | |||
279 | }; | ||
280 | |||
281 | |||
282 | /** | ||
283 | * Iterator for local get request results, | ||
284 | * | ||
285 | * @param cls closure with the `struct GNUNET_HashCode *` with the trail ID | ||
286 | * @param key the key this data is stored under | ||
287 | * @param size the size of the data identified by key | ||
288 | * @param data the actual data | ||
289 | * @param type the type of the data | ||
290 | * @param exp when does this value expire? | ||
291 | * @param put_path_length number of peers in @a put_path | ||
292 | * @param put_path path the reply took on put | ||
293 | * @return #GNUNET_OK to continue iteration, anything else | ||
294 | * to stop iteration. | ||
295 | */ | ||
296 | static enum GNUNET_GenericReturnValue | ||
297 | datacache_get_successors_iterator (void *cls, | ||
298 | const struct GNUNET_HashCode *key, | ||
299 | size_t size, | ||
300 | const char *data, | ||
301 | enum GNUNET_BLOCK_Type type, | ||
302 | struct GNUNET_TIME_Absolute exp, | ||
303 | unsigned int put_path_length, | ||
304 | const struct | ||
305 | GNUNET_DHT_PathElement *put_path) | ||
306 | { | ||
307 | const struct SuccContext *sc = cls; | ||
308 | struct GDS_DATACACHE_BlockData bd = { | ||
309 | .key = *key, | ||
310 | .expiration_time = exp, | ||
311 | .put_path = put_path, | ||
312 | .data = data, | ||
313 | .data_size = size, | ||
314 | .put_path_length = put_path_length, | ||
315 | .type = type | ||
316 | }; | ||
317 | |||
318 | /* NOTE: The datacache currently does not store the RO from | ||
319 | the original 'put', so we don't know the 'correct' option | ||
320 | at this point anymore. Thus, we conservatively assume | ||
321 | that recording is desired (for now). */ | ||
322 | sc->cb (sc->cb_cls, | ||
323 | &bd); | ||
324 | return GNUNET_OK; | ||
325 | } | ||
326 | |||
327 | |||
328 | void | ||
329 | GDS_DATACACHE_get_closest (const struct GNUNET_HashCode *key, | 266 | GDS_DATACACHE_get_closest (const struct GNUNET_HashCode *key, |
267 | enum GNUNET_BLOCK_Type type, | ||
268 | const void *xquery, | ||
269 | size_t xquery_size, | ||
270 | struct GNUNET_BLOCK_Group *bg, | ||
330 | GDS_DATACACHE_GetCallback cb, | 271 | GDS_DATACACHE_GetCallback cb, |
331 | void *cb_cls) | 272 | void *cb_cls) |
332 | { | 273 | { |
333 | struct SuccContext sc = { | 274 | struct GetRequestContext ctx = { |
334 | .cb = cb, | 275 | .eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID, |
335 | .cb_cls = cb_cls | 276 | .key = *key, |
277 | .xquery = xquery, | ||
278 | .xquery_size = xquery_size, | ||
279 | .bg = bg, | ||
280 | .gc = cb, | ||
281 | .gc_cls = cb_cls | ||
336 | }; | 282 | }; |
283 | unsigned int r; | ||
337 | 284 | ||
338 | (void) GNUNET_DATACACHE_get_closest (datacache, | 285 | if (NULL == datacache) |
339 | key, | 286 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; |
340 | NUM_CLOSEST, | 287 | GNUNET_STATISTICS_update (GDS_stats, |
341 | &datacache_get_successors_iterator, | 288 | "# GET closest requests given to datacache", |
342 | &sc); | 289 | 1, |
290 | GNUNET_NO); | ||
291 | r = GNUNET_DATACACHE_get_closest (datacache, | ||
292 | key, | ||
293 | type, | ||
294 | NUM_CLOSEST, | ||
295 | &datacache_get_iterator, | ||
296 | &ctx); | ||
297 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
298 | "DATACACHE approximate GET for key %s completed (%d). %u results found.\n", | ||
299 | GNUNET_h2s (key), | ||
300 | ctx.eval, | ||
301 | r); | ||
302 | return ctx.eval; | ||
343 | } | 303 | } |
344 | 304 | ||
345 | 305 | ||
diff --git a/src/dht/gnunet-service-dht_datacache.h b/src/dht/gnunet-service-dht_datacache.h index 691a51e0e..69a18c605 100644 --- a/src/dht/gnunet-service-dht_datacache.h +++ b/src/dht/gnunet-service-dht_datacache.h | |||
@@ -122,11 +122,20 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
122 | * another peer. | 122 | * another peer. |
123 | * | 123 | * |
124 | * @param key the location at which the peer is looking for data that is close | 124 | * @param key the location at which the peer is looking for data that is close |
125 | * @param type requested data type | ||
126 | * @param xquery extended query | ||
127 | * @param xquery_size number of bytes in xquery | ||
128 | * @param bg block group to use for evaluation of replies | ||
125 | * @param cb function to call with the result | 129 | * @param cb function to call with the result |
126 | * @param cb_cls closure for @a cb | 130 | * @param cb_cls closure for @a cb |
131 | * @return evaluation result for the local replies | ||
127 | */ | 132 | */ |
128 | void | 133 | enum GNUNET_BLOCK_EvaluationResult |
129 | GDS_DATACACHE_get_closest (const struct GNUNET_HashCode *key, | 134 | GDS_DATACACHE_get_closest (const struct GNUNET_HashCode *key, |
135 | enum GNUNET_BLOCK_Type type, | ||
136 | const void *xquery, | ||
137 | size_t xquery_size, | ||
138 | struct GNUNET_BLOCK_Group *bg, | ||
130 | GDS_DATACACHE_GetCallback cb, | 139 | GDS_DATACACHE_GetCallback cb, |
131 | void *cb_cls); | 140 | void *cb_cls); |
132 | 141 | ||
diff --git a/src/dht/gnunet-service-dht_hello.c b/src/dht/gnunet-service-dht_hello.c deleted file mode 100644 index 949456575..000000000 --- a/src/dht/gnunet-service-dht_hello.c +++ /dev/null | |||
@@ -1,154 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-dht_hello.c | ||
23 | * @brief GNUnet DHT integration with peerinfo | ||
24 | * @author Christian Grothoff | ||
25 | * | ||
26 | * TODO: | ||
27 | * - consider adding mechanism to remove expired HELLOs | ||
28 | */ | ||
29 | #include "platform.h" | ||
30 | #include "gnunet-service-dht.h" | ||
31 | #include "gnunet-service-dht_hello.h" | ||
32 | #include "gnunet_peerinfo_service.h" | ||
33 | |||
34 | |||
35 | /** | ||
36 | * Handle for peerinfo notifications. | ||
37 | */ | ||
38 | static struct GNUNET_PEERINFO_NotifyContext *pnc; | ||
39 | |||
40 | /** | ||
41 | * Hash map of peers to HELLOs. | ||
42 | */ | ||
43 | static struct GNUNET_CONTAINER_MultiPeerMap *peer_to_hello; | ||
44 | |||
45 | |||
46 | /** | ||
47 | * Obtain a peer's HELLO if available | ||
48 | * | ||
49 | * @param peer peer to look for a HELLO from | ||
50 | * @return HELLO for the given peer | ||
51 | */ | ||
52 | const struct GNUNET_HELLO_Message * | ||
53 | GDS_HELLO_get (const struct GNUNET_PeerIdentity *peer) | ||
54 | { | ||
55 | if (NULL == peer_to_hello) | ||
56 | return NULL; | ||
57 | return GNUNET_CONTAINER_multipeermap_get (peer_to_hello, | ||
58 | peer); | ||
59 | } | ||
60 | |||
61 | |||
62 | /** | ||
63 | * Function called for each HELLO known to PEERINFO. | ||
64 | * | ||
65 | * @param cls closure | ||
66 | * @param peer id of the peer, NULL for last call | ||
67 | * @param hello hello message for the peer (can be NULL) | ||
68 | * @param err_msg error message (not used) | ||
69 | * | ||
70 | * FIXME this is called once per address. Merge instead of replacing? | ||
71 | */ | ||
72 | static void | ||
73 | process_hello (void *cls, | ||
74 | const struct GNUNET_PeerIdentity *peer, | ||
75 | const struct GNUNET_HELLO_Message *hello, | ||
76 | const char *err_msg) | ||
77 | { | ||
78 | struct GNUNET_TIME_Absolute ex; | ||
79 | struct GNUNET_HELLO_Message *hm; | ||
80 | |||
81 | if (NULL == hello) | ||
82 | return; | ||
83 | ex = GNUNET_HELLO_get_last_expiration (hello); | ||
84 | if (0 == GNUNET_TIME_absolute_get_remaining (ex).rel_value_us) | ||
85 | return; | ||
86 | GNUNET_STATISTICS_update (GDS_stats, | ||
87 | "# HELLOs obtained from peerinfo", | ||
88 | 1, | ||
89 | GNUNET_NO); | ||
90 | hm = GNUNET_CONTAINER_multipeermap_get (peer_to_hello, | ||
91 | peer); | ||
92 | GNUNET_free (hm); | ||
93 | hm = GNUNET_malloc (GNUNET_HELLO_size (hello)); | ||
94 | GNUNET_memcpy (hm, | ||
95 | hello, | ||
96 | GNUNET_HELLO_size (hello)); | ||
97 | GNUNET_assert (GNUNET_SYSERR != | ||
98 | GNUNET_CONTAINER_multipeermap_put (peer_to_hello, | ||
99 | peer, | ||
100 | hm, | ||
101 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)); | ||
102 | } | ||
103 | |||
104 | |||
105 | /** | ||
106 | * Initialize HELLO subsystem. | ||
107 | */ | ||
108 | void | ||
109 | GDS_HELLO_init () | ||
110 | { | ||
111 | pnc = GNUNET_PEERINFO_notify (GDS_cfg, | ||
112 | GNUNET_NO, | ||
113 | &process_hello, | ||
114 | NULL); | ||
115 | peer_to_hello = GNUNET_CONTAINER_multipeermap_create (256, | ||
116 | GNUNET_NO); | ||
117 | } | ||
118 | |||
119 | |||
120 | /** | ||
121 | * Free memory occopied by the HELLO. | ||
122 | */ | ||
123 | static enum GNUNET_GenericReturnValue | ||
124 | free_hello (void *cls, | ||
125 | const struct GNUNET_PeerIdentity *key, | ||
126 | void *hello) | ||
127 | { | ||
128 | GNUNET_free (hello); | ||
129 | return GNUNET_OK; | ||
130 | } | ||
131 | |||
132 | |||
133 | /** | ||
134 | * Shutdown HELLO subsystem. | ||
135 | */ | ||
136 | void | ||
137 | GDS_HELLO_done () | ||
138 | { | ||
139 | if (NULL != pnc) | ||
140 | { | ||
141 | GNUNET_PEERINFO_notify_cancel (pnc); | ||
142 | pnc = NULL; | ||
143 | } | ||
144 | if (NULL != peer_to_hello) | ||
145 | { | ||
146 | GNUNET_CONTAINER_multipeermap_iterate (peer_to_hello, | ||
147 | &free_hello, | ||
148 | NULL); | ||
149 | GNUNET_CONTAINER_multipeermap_destroy (peer_to_hello); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | |||
154 | /* end of gnunet-service-dht_hello.c */ | ||
diff --git a/src/dht/gnunet-service-dht_hello.h b/src/dht/gnunet-service-dht_hello.h deleted file mode 100644 index f8b90862d..000000000 --- a/src/dht/gnunet-service-dht_hello.h +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-dht_hello.h | ||
23 | * @brief GNUnet DHT integration with peerinfo | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #ifndef GNUNET_SERVICE_DHT_HELLO_H | ||
27 | #define GNUNET_SERVICE_DHT_HELLO_H | ||
28 | |||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_hello_lib.h" | ||
31 | |||
32 | /** | ||
33 | * Obtain a peer's HELLO if available | ||
34 | * | ||
35 | * @param peer peer to look for a HELLO from | ||
36 | * @return HELLO for the given peer | ||
37 | */ | ||
38 | const struct GNUNET_HELLO_Message * | ||
39 | GDS_HELLO_get (const struct GNUNET_PeerIdentity *peer); | ||
40 | |||
41 | |||
42 | /** | ||
43 | * Initialize HELLO subsystem. | ||
44 | */ | ||
45 | void | ||
46 | GDS_HELLO_init (void); | ||
47 | |||
48 | |||
49 | /** | ||
50 | * Shutdown HELLO subsystem. | ||
51 | */ | ||
52 | void | ||
53 | GDS_HELLO_done (void); | ||
54 | |||
55 | #endif | ||
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index bc473df69..b7b5e8097 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c | |||
@@ -29,8 +29,8 @@ | |||
29 | #include "gnunet_protocols.h" | 29 | #include "gnunet_protocols.h" |
30 | #include "gnunet_signatures.h" | 30 | #include "gnunet_signatures.h" |
31 | #include "gnunet_hello_lib.h" | 31 | #include "gnunet_hello_lib.h" |
32 | #include "gnunet_hello_uri_lib.h" | ||
32 | #include "gnunet-service-dht.h" | 33 | #include "gnunet-service-dht.h" |
33 | #include "gnunet-service-dht_hello.h" | ||
34 | #include "gnunet-service-dht_neighbours.h" | 34 | #include "gnunet-service-dht_neighbours.h" |
35 | #include "gnunet-service-dht_routing.h" | 35 | #include "gnunet-service-dht_routing.h" |
36 | #include "dht.h" | 36 | #include "dht.h" |
@@ -88,11 +88,6 @@ | |||
88 | */ | 88 | */ |
89 | #define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) | 89 | #define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) |
90 | 90 | ||
91 | /** | ||
92 | * Hello address expiration | ||
93 | */ | ||
94 | extern struct GNUNET_TIME_Relative hello_expiration; | ||
95 | |||
96 | 91 | ||
97 | GNUNET_NETWORK_STRUCT_BEGIN | 92 | GNUNET_NETWORK_STRUCT_BEGIN |
98 | 93 | ||
@@ -260,81 +255,129 @@ GNUNET_NETWORK_STRUCT_END | |||
260 | /** | 255 | /** |
261 | * Entry for a peer in a bucket. | 256 | * Entry for a peer in a bucket. |
262 | */ | 257 | */ |
263 | struct PeerInfo | 258 | struct PeerInfo; |
259 | |||
260 | |||
261 | /** | ||
262 | * List of targets that we can use to reach this peer. | ||
263 | */ | ||
264 | struct Target | ||
264 | { | 265 | { |
265 | /** | 266 | /** |
266 | * Next peer entry (DLL) | 267 | * Kept in a DLL. |
267 | */ | 268 | */ |
268 | struct PeerInfo *next; | 269 | struct Target *next; |
269 | 270 | ||
270 | /** | 271 | /** |
271 | * Prev peer entry (DLL) | 272 | * Kept in a DLL. |
272 | */ | 273 | */ |
273 | struct PeerInfo *prev; | 274 | struct Target *prev; |
274 | 275 | ||
275 | /** | 276 | /** |
276 | * Handle for sending messages to this peer. | 277 | * Handle for sending messages to this peer. |
277 | */ | 278 | */ |
278 | struct GNUNET_DHTU_Target *target; | 279 | struct GNUNET_DHTU_Target *utarget; |
279 | 280 | ||
280 | /** | 281 | /** |
281 | * What is the identity of the peer? | 282 | * Underlay providing this target. |
282 | */ | 283 | */ |
283 | struct GNUNET_PeerIdentity id; | 284 | struct Underlay *u; |
284 | 285 | ||
285 | /** | 286 | /** |
286 | * Hash of @e id. | 287 | * Peer this is a target for. |
287 | */ | 288 | */ |
288 | struct GNUNET_HashCode phash; | 289 | struct PeerInfo *pi; |
289 | 290 | ||
290 | /** | 291 | /** |
291 | * Which bucket is this peer in? | 292 | * Set to number of messages are waiting for the transmission to finish. |
292 | */ | 293 | */ |
293 | int peer_bucket; | 294 | unsigned int load; |
295 | |||
296 | /** | ||
297 | * Set to @a true if the target was dropped, but we could not clean | ||
298 | * up yet because @e busy was also true. | ||
299 | */ | ||
300 | bool dropped; | ||
301 | |||
294 | }; | 302 | }; |
295 | 303 | ||
296 | 304 | ||
297 | /** | 305 | /** |
298 | * Peers are grouped into buckets. | 306 | * Entry for a peer in a bucket. |
299 | */ | 307 | */ |
300 | struct PeerBucket | 308 | struct PeerInfo |
301 | { | 309 | { |
302 | /** | 310 | /** |
303 | * Head of DLL | 311 | * What is the identity of the peer? |
304 | */ | 312 | */ |
305 | struct PeerInfo *head; | 313 | struct GNUNET_PeerIdentity id; |
306 | 314 | ||
307 | /** | 315 | /** |
308 | * Tail of DLL | 316 | * Hash of @e id. |
309 | */ | 317 | */ |
310 | struct PeerInfo *tail; | 318 | struct GNUNET_HashCode phash; |
311 | 319 | ||
312 | /** | 320 | /** |
313 | * Number of peers in the bucket. | 321 | * When does our HELLO from this peer expire? |
314 | */ | 322 | */ |
315 | unsigned int peers_size; | 323 | struct GNUNET_TIME_Absolute hello_expiration; |
324 | |||
325 | /** | ||
326 | * Next peer entry (DLL) | ||
327 | */ | ||
328 | struct PeerInfo *next; | ||
329 | |||
330 | /** | ||
331 | * Prev peer entry (DLL) | ||
332 | */ | ||
333 | struct PeerInfo *prev; | ||
334 | |||
335 | /** | ||
336 | * Head of DLL of targets for this peer. | ||
337 | */ | ||
338 | struct Target *t_head; | ||
339 | |||
340 | /** | ||
341 | * Tail of DLL of targets for this peer. | ||
342 | */ | ||
343 | struct Target *t_tail; | ||
344 | |||
345 | /** | ||
346 | * Block with a HELLO of this peer. | ||
347 | */ | ||
348 | void *hello; | ||
349 | |||
350 | /** | ||
351 | * Number of bytes in @e hello. | ||
352 | */ | ||
353 | size_t hello_size; | ||
354 | |||
355 | /** | ||
356 | * Which bucket is this peer in? | ||
357 | */ | ||
358 | int peer_bucket; | ||
316 | }; | 359 | }; |
317 | 360 | ||
318 | 361 | ||
319 | /** | 362 | /** |
320 | * Information about a peer that we would like to connect to. | 363 | * Peers are grouped into buckets. |
321 | */ | 364 | */ |
322 | struct ConnectInfo | 365 | struct PeerBucket |
323 | { | 366 | { |
324 | /** | 367 | /** |
325 | * Handle to active HELLO offer operation, or NULL. | 368 | * Head of DLL |
326 | */ | 369 | */ |
327 | struct GNUNET_TRANSPORT_OfferHelloHandle *oh; | 370 | struct PeerInfo *head; |
328 | 371 | ||
329 | /** | 372 | /** |
330 | * Handle to active connectivity suggestion operation, or NULL. | 373 | * Tail of DLL |
331 | */ | 374 | */ |
332 | struct GNUNET_DHTU_PreferenceHandle *ph; | 375 | struct PeerInfo *tail; |
333 | 376 | ||
334 | /** | 377 | /** |
335 | * How much would we like to connect to this peer? | 378 | * Number of peers in the bucket. |
336 | */ | 379 | */ |
337 | uint32_t strength; | 380 | unsigned int peers_size; |
338 | }; | 381 | }; |
339 | 382 | ||
340 | 383 | ||
@@ -371,12 +414,6 @@ static struct PeerBucket k_buckets[MAX_BUCKETS]; | |||
371 | static struct GNUNET_CONTAINER_MultiPeerMap *all_connected_peers; | 414 | static struct GNUNET_CONTAINER_MultiPeerMap *all_connected_peers; |
372 | 415 | ||
373 | /** | 416 | /** |
374 | * Hash map of all peers we would like to be connected to. | ||
375 | * Values are of type `struct ConnectInfo`. | ||
376 | */ | ||
377 | static struct GNUNET_CONTAINER_MultiPeerMap *all_desired_peers; | ||
378 | |||
379 | /** | ||
380 | * Maximum size for each bucket. | 417 | * Maximum size for each bucket. |
381 | */ | 418 | */ |
382 | static unsigned int bucket_size = DEFAULT_BUCKET_SIZE; | 419 | static unsigned int bucket_size = DEFAULT_BUCKET_SIZE; |
@@ -386,20 +423,83 @@ static unsigned int bucket_size = DEFAULT_BUCKET_SIZE; | |||
386 | */ | 423 | */ |
387 | static struct GNUNET_SCHEDULER_Task *find_peer_task; | 424 | static struct GNUNET_SCHEDULER_Task *find_peer_task; |
388 | 425 | ||
389 | /** | ||
390 | * Identity of this peer. | ||
391 | */ | ||
392 | static struct GNUNET_PeerIdentity my_identity; | ||
393 | 426 | ||
394 | /** | 427 | /** |
395 | * Hash of the identity of this peer. | 428 | * Function called whenever we finished sending to a target. |
429 | * Marks the transmission as finished (and the target as ready | ||
430 | * for the next message). | ||
431 | * | ||
432 | * @param cls a `struct Target *` | ||
396 | */ | 433 | */ |
397 | struct GNUNET_HashCode my_identity_hash; | 434 | static void |
435 | send_done_cb (void *cls) | ||
436 | { | ||
437 | struct Target *t = cls; | ||
438 | struct PeerInfo *pi = t->pi; /* NULL if t->dropped! */ | ||
439 | |||
440 | GNUNET_assert (t->load > 0); | ||
441 | t->load--; | ||
442 | if (0 < t->load) | ||
443 | return; | ||
444 | if (t->dropped) | ||
445 | { | ||
446 | GNUNET_free (t); | ||
447 | return; | ||
448 | } | ||
449 | /* move target back to the front */ | ||
450 | GNUNET_CONTAINER_DLL_remove (pi->t_head, | ||
451 | pi->t_tail, | ||
452 | t); | ||
453 | GNUNET_CONTAINER_DLL_insert (pi->t_head, | ||
454 | pi->t_tail, | ||
455 | t); | ||
456 | } | ||
457 | |||
398 | 458 | ||
399 | /** | 459 | /** |
400 | * Our private key. | 460 | * Send @a msg to @a pi. |
461 | * | ||
462 | * @param pi where to send the message | ||
463 | * @param msg message to send | ||
401 | */ | 464 | */ |
402 | static struct GNUNET_CRYPTO_EddsaPrivateKey my_private_key; | 465 | static void |
466 | do_send (struct PeerInfo *pi, | ||
467 | const struct GNUNET_MessageHeader *msg) | ||
468 | { | ||
469 | struct Target *t; | ||
470 | |||
471 | for (t = pi->t_head; | ||
472 | NULL != t; | ||
473 | t = t->next) | ||
474 | if (t->load < MAXIMUM_PENDING_PER_PEER) | ||
475 | break; | ||
476 | if (NULL == t) | ||
477 | { | ||
478 | /* all targets busy, drop message */ | ||
479 | GNUNET_STATISTICS_update (GDS_stats, | ||
480 | "# messages dropped (underlays busy)", | ||
481 | 1, | ||
482 | GNUNET_NO); | ||
483 | return; | ||
484 | } | ||
485 | t->load++; | ||
486 | /* rotate busy targets to the end */ | ||
487 | if (MAXIMUM_PENDING_PER_PEER == t->load) | ||
488 | { | ||
489 | GNUNET_CONTAINER_DLL_remove (pi->t_head, | ||
490 | pi->t_tail, | ||
491 | t); | ||
492 | GNUNET_CONTAINER_DLL_insert_tail (pi->t_head, | ||
493 | pi->t_tail, | ||
494 | t); | ||
495 | } | ||
496 | GDS_u_send (t->u, | ||
497 | t->utarget, | ||
498 | msg, | ||
499 | ntohs (msg->size), | ||
500 | &send_done_cb, | ||
501 | t); | ||
502 | } | ||
403 | 503 | ||
404 | 504 | ||
405 | /** | 505 | /** |
@@ -436,7 +536,7 @@ sign_path (const struct GNUNET_HashCode *key, | |||
436 | GNUNET_CRYPTO_hash (data, | 536 | GNUNET_CRYPTO_hash (data, |
437 | data_size, | 537 | data_size, |
438 | &hs.h_data); | 538 | &hs.h_data); |
439 | GNUNET_CRYPTO_eddsa_sign (&my_private_key, | 539 | GNUNET_CRYPTO_eddsa_sign (&GDS_my_private_key, |
440 | &hs, | 540 | &hs, |
441 | sig); | 541 | sig); |
442 | } | 542 | } |
@@ -456,7 +556,7 @@ find_bucket (const struct GNUNET_HashCode *hc) | |||
456 | unsigned int bits; | 556 | unsigned int bits; |
457 | 557 | ||
458 | GNUNET_CRYPTO_hash_xor (hc, | 558 | GNUNET_CRYPTO_hash_xor (hc, |
459 | &my_identity_hash, | 559 | &GDS_my_identity_hash, |
460 | &xor); | 560 | &xor); |
461 | bits = GNUNET_CRYPTO_hash_count_leading_zeros (&xor); | 561 | bits = GNUNET_CRYPTO_hash_count_leading_zeros (&xor); |
462 | if (bits == MAX_BUCKETS) | 562 | if (bits == MAX_BUCKETS) |
@@ -470,175 +570,6 @@ find_bucket (const struct GNUNET_HashCode *hc) | |||
470 | 570 | ||
471 | 571 | ||
472 | /** | 572 | /** |
473 | * Function called when #GNUNET_TRANSPORT_offer_hello() is done. | ||
474 | * Clean up the "oh" field in the @a cls | ||
475 | * | ||
476 | * @param cls a `struct ConnectInfo` | ||
477 | */ | ||
478 | static void | ||
479 | offer_hello_done (void *cls) | ||
480 | { | ||
481 | struct ConnectInfo *ci = cls; | ||
482 | |||
483 | ci->oh = NULL; | ||
484 | } | ||
485 | |||
486 | |||
487 | /** | ||
488 | * Function called for all entries in #all_desired_peers to clean up. | ||
489 | * | ||
490 | * @param cls NULL | ||
491 | * @param peer peer the entry is for | ||
492 | * @param value the value to remove | ||
493 | * @return #GNUNET_YES | ||
494 | */ | ||
495 | static enum GNUNET_GenericReturnValue | ||
496 | free_connect_info (void *cls, | ||
497 | const struct GNUNET_PeerIdentity *peer, | ||
498 | void *value) | ||
499 | { | ||
500 | struct ConnectInfo *ci = value; | ||
501 | |||
502 | (void) cls; | ||
503 | GNUNET_assert (GNUNET_YES == | ||
504 | GNUNET_CONTAINER_multipeermap_remove (all_desired_peers, | ||
505 | peer, | ||
506 | ci)); | ||
507 | if (NULL != ci->ph) | ||
508 | { | ||
509 | // ci->u->drop (ci->ph); // FIXME! | ||
510 | ci->ph = NULL; | ||
511 | } | ||
512 | if (NULL != ci->oh) | ||
513 | { | ||
514 | GNUNET_TRANSPORT_offer_hello_cancel (ci->oh); | ||
515 | ci->oh = NULL; | ||
516 | } | ||
517 | GNUNET_free (ci); | ||
518 | return GNUNET_YES; | ||
519 | } | ||
520 | |||
521 | |||
522 | /** | ||
523 | * Consider if we want to connect to a given peer, and if so | ||
524 | * let ATS know. If applicable, the HELLO is offered to the | ||
525 | * TRANSPORT service. | ||
526 | * | ||
527 | * @param pid peer to consider connectivity requirements for | ||
528 | * @param h a HELLO message, or NULL | ||
529 | */ | ||
530 | static void | ||
531 | try_connect (const struct GNUNET_PeerIdentity *pid, | ||
532 | const struct GNUNET_MessageHeader *h) | ||
533 | { | ||
534 | int bucket_idx; | ||
535 | struct GNUNET_HashCode pid_hash; | ||
536 | struct ConnectInfo *ci; | ||
537 | uint32_t strength; | ||
538 | struct PeerBucket *bucket; | ||
539 | |||
540 | GNUNET_CRYPTO_hash (pid, | ||
541 | sizeof(struct GNUNET_PeerIdentity), | ||
542 | &pid_hash); | ||
543 | bucket_idx = find_bucket (&pid_hash); | ||
544 | if (bucket_idx < 0) | ||
545 | { | ||
546 | GNUNET_break (0); | ||
547 | return; /* self!? */ | ||
548 | } | ||
549 | bucket = &k_buckets[bucket_idx]; | ||
550 | ci = GNUNET_CONTAINER_multipeermap_get (all_desired_peers, | ||
551 | pid); | ||
552 | if (bucket->peers_size < bucket_size) | ||
553 | strength = (bucket_size - bucket->peers_size) * bucket_idx; | ||
554 | else | ||
555 | strength = 0; | ||
556 | if (GNUNET_YES == | ||
557 | GNUNET_CONTAINER_multipeermap_contains (all_connected_peers, | ||
558 | pid)) | ||
559 | strength *= 2; /* double for connected peers */ | ||
560 | if ( (0 == strength) && | ||
561 | (NULL != ci) ) | ||
562 | { | ||
563 | /* release request */ | ||
564 | GNUNET_assert (GNUNET_YES == | ||
565 | free_connect_info (NULL, | ||
566 | pid, | ||
567 | ci)); | ||
568 | return; | ||
569 | } | ||
570 | if (NULL == ci) | ||
571 | { | ||
572 | ci = GNUNET_new (struct ConnectInfo); | ||
573 | GNUNET_assert (GNUNET_OK == | ||
574 | GNUNET_CONTAINER_multipeermap_put (all_desired_peers, | ||
575 | pid, | ||
576 | ci, | ||
577 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
578 | } | ||
579 | if ( (NULL != ci->oh) && | ||
580 | (NULL != h) ) | ||
581 | GNUNET_TRANSPORT_offer_hello_cancel (ci->oh); | ||
582 | if (NULL != h) | ||
583 | ci->oh = GNUNET_TRANSPORT_offer_hello (GDS_cfg, | ||
584 | h, | ||
585 | &offer_hello_done, | ||
586 | ci); | ||
587 | if ( (NULL != ci->ph) && | ||
588 | (ci->strength != strength) ) | ||
589 | { | ||
590 | // ci->u_api->drop (ci->ph); | ||
591 | ci->ph = NULL; | ||
592 | } | ||
593 | if (ci->strength != strength) | ||
594 | { | ||
595 | #if FIXME | ||
596 | ci->ph = ci->u_api->hold (ci->u_api->cls, | ||
597 | TARGET); | ||
598 | #endif | ||
599 | ci->strength = strength; | ||
600 | } | ||
601 | } | ||
602 | |||
603 | |||
604 | /** | ||
605 | * Function called for each peer in #all_desired_peers during | ||
606 | * #update_connect_preferences() if we have reason to adjust | ||
607 | * the strength of our desire to keep connections to certain | ||
608 | * peers. Calls #try_connect() to update the calculations for | ||
609 | * the given @a pid. | ||
610 | * | ||
611 | * @param cls NULL | ||
612 | * @param pid peer to update | ||
613 | * @param value unused | ||
614 | * @return #GNUNET_YES (continue to iterate) | ||
615 | */ | ||
616 | static enum GNUNET_GenericReturnValue | ||
617 | update_desire_strength (void *cls, | ||
618 | const struct GNUNET_PeerIdentity *pid, | ||
619 | void *value) | ||
620 | { | ||
621 | (void) cls; | ||
622 | (void) value; | ||
623 | try_connect (pid, | ||
624 | NULL); | ||
625 | return GNUNET_YES; | ||
626 | } | ||
627 | |||
628 | |||
629 | /** | ||
630 | * Update our preferences for connectivity as given to ATS. | ||
631 | */ | ||
632 | static void | ||
633 | update_connect_preferences (void) | ||
634 | { | ||
635 | GNUNET_CONTAINER_multipeermap_iterate (all_desired_peers, | ||
636 | &update_desire_strength, | ||
637 | NULL); | ||
638 | } | ||
639 | |||
640 | |||
641 | /** | ||
642 | * Add each of the peers we already know to the Bloom filter of | 573 | * Add each of the peers we already know to the Bloom filter of |
643 | * the request so that we don't get duplicate HELLOs. | 574 | * the request so that we don't get duplicate HELLOs. |
644 | * | 575 | * |
@@ -728,11 +659,11 @@ send_find_peer_message (void *cls) | |||
728 | GNUNET_CONSTANTS_BLOOMFILTER_K); | 659 | GNUNET_CONSTANTS_BLOOMFILTER_K); |
729 | if (GNUNET_OK != | 660 | if (GNUNET_OK != |
730 | GDS_NEIGHBOURS_handle_get (GNUNET_BLOCK_TYPE_DHT_URL_HELLO, | 661 | GDS_NEIGHBOURS_handle_get (GNUNET_BLOCK_TYPE_DHT_URL_HELLO, |
731 | GNUNET_DHT_RO_FIND_PEER | 662 | GNUNET_DHT_RO_FIND_APPROXIMATE |
732 | | GNUNET_DHT_RO_RECORD_ROUTE, | 663 | | GNUNET_DHT_RO_RECORD_ROUTE, |
733 | FIND_PEER_REPLICATION_LEVEL, | 664 | FIND_PEER_REPLICATION_LEVEL, |
734 | 0, /* hop count */ | 665 | 0, /* hop count */ |
735 | &my_identity_hash, | 666 | &GDS_my_identity_hash, |
736 | NULL, 0, /* xquery */ | 667 | NULL, 0, /* xquery */ |
737 | bg, | 668 | bg, |
738 | peer_bf)) | 669 | peer_bf)) |
@@ -761,106 +692,131 @@ GDS_u_connect (void *cls, | |||
761 | const struct GNUNET_PeerIdentity *pid, | 692 | const struct GNUNET_PeerIdentity *pid, |
762 | void **ctx) | 693 | void **ctx) |
763 | { | 694 | { |
695 | struct Underlay *u = cls; | ||
764 | struct PeerInfo *pi; | 696 | struct PeerInfo *pi; |
765 | struct PeerBucket *bucket; | 697 | struct PeerBucket *bucket; |
766 | 698 | ||
767 | (void) cls; | ||
768 | /* Check for connect to self message */ | 699 | /* Check for connect to self message */ |
769 | if (0 == GNUNET_memcmp (&my_identity, | 700 | if (0 == GNUNET_memcmp (&GDS_my_identity, |
770 | pid)) | 701 | pid)) |
771 | return; | 702 | return; |
772 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 703 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
773 | "Connected to peer %s\n", | 704 | "Connected to peer %s\n", |
774 | GNUNET_i2s (pid)); | 705 | GNUNET_i2s (pid)); |
775 | GNUNET_assert (NULL == | 706 | pi = GNUNET_CONTAINER_multipeermap_get (all_connected_peers, |
776 | GNUNET_CONTAINER_multipeermap_get (all_connected_peers, | 707 | pid); |
777 | pid)); | 708 | if (NULL == pi) |
778 | GNUNET_STATISTICS_update (GDS_stats, | ||
779 | "# peers connected", | ||
780 | 1, | ||
781 | GNUNET_NO); | ||
782 | pi = GNUNET_new (struct PeerInfo); | ||
783 | pi->id = *pid; | ||
784 | pi->target = target; | ||
785 | GNUNET_CRYPTO_hash (pid, | ||
786 | sizeof(*pid), | ||
787 | &pi->phash); | ||
788 | pi->peer_bucket = find_bucket (&pi->phash); | ||
789 | GNUNET_assert ( (pi->peer_bucket >= 0) && | ||
790 | ((unsigned int) pi->peer_bucket < MAX_BUCKETS)); | ||
791 | bucket = &k_buckets[pi->peer_bucket]; | ||
792 | GNUNET_CONTAINER_DLL_insert_tail (bucket->head, | ||
793 | bucket->tail, | ||
794 | pi); | ||
795 | bucket->peers_size++; | ||
796 | closest_bucket = GNUNET_MAX (closest_bucket, | ||
797 | (unsigned int) pi->peer_bucket + 1); | ||
798 | GNUNET_assert (GNUNET_OK == | ||
799 | GNUNET_CONTAINER_multipeermap_put (all_connected_peers, | ||
800 | &pi->id, | ||
801 | pi, | ||
802 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
803 | if (bucket->peers_size <= bucket_size) | ||
804 | { | 709 | { |
805 | update_connect_preferences (); | 710 | GNUNET_STATISTICS_update (GDS_stats, |
806 | newly_found_peers++; | 711 | "# peers connected", |
712 | 1, | ||
713 | GNUNET_NO); | ||
714 | pi = GNUNET_new (struct PeerInfo); | ||
715 | pi->id = *pid; | ||
716 | GNUNET_CRYPTO_hash (pid, | ||
717 | sizeof(*pid), | ||
718 | &pi->phash); | ||
719 | pi->peer_bucket = find_bucket (&pi->phash); | ||
720 | GNUNET_assert ( (pi->peer_bucket >= 0) && | ||
721 | ((unsigned int) pi->peer_bucket < MAX_BUCKETS)); | ||
722 | bucket = &k_buckets[pi->peer_bucket]; | ||
723 | GNUNET_CONTAINER_DLL_insert_tail (bucket->head, | ||
724 | bucket->tail, | ||
725 | pi); | ||
726 | bucket->peers_size++; | ||
727 | closest_bucket = GNUNET_MAX (closest_bucket, | ||
728 | (unsigned int) pi->peer_bucket + 1); | ||
729 | GNUNET_assert (GNUNET_OK == | ||
730 | GNUNET_CONTAINER_multipeermap_put (all_connected_peers, | ||
731 | &pi->id, | ||
732 | pi, | ||
733 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
734 | if (bucket->peers_size <= bucket_size) | ||
735 | { | ||
736 | newly_found_peers++; | ||
737 | // FIXME: call 'hold'! | ||
738 | } | ||
739 | if ( (1 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && | ||
740 | (GNUNET_YES != disable_try_connect) ) | ||
741 | { | ||
742 | /* got a first connection, good time to start with FIND PEER requests... */ | ||
743 | GNUNET_assert (NULL == find_peer_task); | ||
744 | find_peer_task = GNUNET_SCHEDULER_add_now (&send_find_peer_message, | ||
745 | NULL); | ||
746 | } | ||
807 | } | 747 | } |
808 | if ( (1 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && | ||
809 | (GNUNET_YES != disable_try_connect) ) | ||
810 | { | 748 | { |
811 | /* got a first connection, good time to start with FIND PEER requests... */ | 749 | struct Target *t; |
812 | GNUNET_assert (NULL == find_peer_task); | 750 | |
813 | find_peer_task = GNUNET_SCHEDULER_add_now (&send_find_peer_message, | 751 | t = GNUNET_new (struct Target); |
814 | NULL); | 752 | t->u = u; |
753 | t->utarget = target; | ||
754 | t->pi = pi; | ||
755 | GNUNET_CONTAINER_DLL_insert (pi->t_head, | ||
756 | pi->t_tail, | ||
757 | t); | ||
758 | *ctx = t; | ||
759 | |||
815 | } | 760 | } |
816 | *ctx = pi; | ||
817 | } | 761 | } |
818 | 762 | ||
819 | 763 | ||
820 | /** | ||
821 | * Method called whenever a peer disconnects. | ||
822 | * | ||
823 | * @param ctx context | ||
824 | */ | ||
825 | void | 764 | void |
826 | GDS_u_disconnect (void *ctx) | 765 | GDS_u_disconnect (void *ctx) |
827 | { | 766 | { |
828 | struct PeerInfo *to_remove = ctx; | 767 | struct Target *t = ctx; |
768 | struct PeerInfo *pi; | ||
829 | struct PeerBucket *bucket; | 769 | struct PeerBucket *bucket; |
830 | 770 | ||
831 | /* Check for disconnect from self message (on shutdown) */ | 771 | /* Check for disconnect from self message (on shutdown) */ |
832 | if (NULL == to_remove) | 772 | if (NULL == t) |
833 | return; | 773 | return; |
774 | pi = t->pi; | ||
775 | GNUNET_CONTAINER_DLL_remove (pi->t_head, | ||
776 | pi->t_tail, | ||
777 | t); | ||
778 | if (t->load > 0) | ||
779 | { | ||
780 | t->dropped = true; | ||
781 | t->pi = NULL; | ||
782 | } | ||
783 | else | ||
784 | { | ||
785 | GNUNET_free (t); | ||
786 | } | ||
787 | if (NULL != pi->t_head) | ||
788 | return; /* got other connections still */ | ||
834 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 789 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
835 | "Disconnected from peer %s\n", | 790 | "Disconnected from peer %s\n", |
836 | GNUNET_i2s (&to_remove->id)); | 791 | GNUNET_i2s (&pi->id)); |
837 | GNUNET_STATISTICS_update (GDS_stats, | 792 | GNUNET_STATISTICS_update (GDS_stats, |
838 | "# peers connected", | 793 | "# peers connected", |
839 | -1, | 794 | -1, |
840 | GNUNET_NO); | 795 | GNUNET_NO); |
841 | GNUNET_assert (GNUNET_YES == | 796 | GNUNET_assert (GNUNET_YES == |
842 | GNUNET_CONTAINER_multipeermap_remove (all_connected_peers, | 797 | GNUNET_CONTAINER_multipeermap_remove (all_connected_peers, |
843 | &to_remove->id, | 798 | &pi->id, |
844 | to_remove)); | 799 | pi)); |
845 | if ( (0 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && | 800 | if ( (0 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && |
846 | (GNUNET_YES != disable_try_connect)) | 801 | (GNUNET_YES != disable_try_connect)) |
847 | { | 802 | { |
848 | GNUNET_SCHEDULER_cancel (find_peer_task); | 803 | GNUNET_SCHEDULER_cancel (find_peer_task); |
849 | find_peer_task = NULL; | 804 | find_peer_task = NULL; |
850 | } | 805 | } |
851 | GNUNET_assert (to_remove->peer_bucket >= 0); | 806 | GNUNET_assert (pi->peer_bucket >= 0); |
852 | bucket = &k_buckets[to_remove->peer_bucket]; | 807 | bucket = &k_buckets[pi->peer_bucket]; |
853 | GNUNET_CONTAINER_DLL_remove (bucket->head, | 808 | GNUNET_CONTAINER_DLL_remove (bucket->head, |
854 | bucket->tail, | 809 | bucket->tail, |
855 | to_remove); | 810 | pi); |
856 | GNUNET_assert (bucket->peers_size > 0); | 811 | GNUNET_assert (bucket->peers_size > 0); |
857 | bucket->peers_size--; | 812 | bucket->peers_size--; |
813 | // FIXME: check if this peer was in one of the first 'bucket_size' | ||
814 | // peers, and call 'hold' on the next peer if there is any! | ||
858 | while ( (closest_bucket > 0) && | 815 | while ( (closest_bucket > 0) && |
859 | (0 == k_buckets[closest_bucket - 1].peers_size)) | 816 | (0 == k_buckets[closest_bucket - 1].peers_size)) |
860 | closest_bucket--; | 817 | closest_bucket--; |
861 | if (bucket->peers_size < bucket_size) | 818 | GNUNET_free (pi->hello); |
862 | update_connect_preferences (); | 819 | GNUNET_free (pi); |
863 | GNUNET_free (to_remove); | ||
864 | } | 820 | } |
865 | 821 | ||
866 | 822 | ||
@@ -935,7 +891,7 @@ enum GNUNET_GenericReturnValue | |||
935 | GDS_am_closest_peer (const struct GNUNET_HashCode *key, | 891 | GDS_am_closest_peer (const struct GNUNET_HashCode *key, |
936 | const struct GNUNET_CONTAINER_BloomFilter *bloom) | 892 | const struct GNUNET_CONTAINER_BloomFilter *bloom) |
937 | { | 893 | { |
938 | if (0 == GNUNET_memcmp (&my_identity_hash, | 894 | if (0 == GNUNET_memcmp (&GDS_my_identity_hash, |
939 | key)) | 895 | key)) |
940 | return GNUNET_YES; | 896 | return GNUNET_YES; |
941 | for (int bucket_num = find_bucket (key); | 897 | for (int bucket_num = find_bucket (key); |
@@ -962,7 +918,7 @@ GDS_am_closest_peer (const struct GNUNET_HashCode *key, | |||
962 | because an unfiltered peer exists, we are not the | 918 | because an unfiltered peer exists, we are not the |
963 | closest. */ | 919 | closest. */ |
964 | int delta = GNUNET_CRYPTO_hash_xorcmp (&pos->phash, | 920 | int delta = GNUNET_CRYPTO_hash_xorcmp (&pos->phash, |
965 | &my_identity_hash, | 921 | &GDS_my_identity_hash, |
966 | key); | 922 | key); |
967 | switch (delta) | 923 | switch (delta) |
968 | { | 924 | { |
@@ -1026,7 +982,7 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1026 | struct GNUNET_HashCode xor; | 982 | struct GNUNET_HashCode xor; |
1027 | 983 | ||
1028 | GNUNET_CRYPTO_hash_xor (key, | 984 | GNUNET_CRYPTO_hash_xor (key, |
1029 | &my_identity_hash, | 985 | &GDS_my_identity_hash, |
1030 | &xor); | 986 | &xor); |
1031 | best_bucket = GNUNET_CRYPTO_hash_count_leading_zeros (&xor); | 987 | best_bucket = GNUNET_CRYPTO_hash_count_leading_zeros (&xor); |
1032 | } | 988 | } |
@@ -1046,9 +1002,10 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1046 | if (count >= bucket_size) | 1002 | if (count >= bucket_size) |
1047 | break; /* we only consider first #bucket_size entries per bucket */ | 1003 | break; /* we only consider first #bucket_size entries per bucket */ |
1048 | count++; | 1004 | count++; |
1049 | if (GNUNET_YES == | 1005 | if ( (NULL != bloom) && |
1050 | GNUNET_CONTAINER_bloomfilter_test (bloom, | 1006 | (GNUNET_YES == |
1051 | &pos->phash)) | 1007 | GNUNET_CONTAINER_bloomfilter_test (bloom, |
1008 | &pos->phash)) ) | ||
1052 | { | 1009 | { |
1053 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1010 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1054 | "Excluded peer `%s' due to BF match in greedy routing for %s\n", | 1011 | "Excluded peer `%s' due to BF match in greedy routing for %s\n", |
@@ -1134,18 +1091,20 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1134 | 1091 | ||
1135 | for (unsigned int bc = 0; bc < closest_bucket; bc++) | 1092 | for (unsigned int bc = 0; bc < closest_bucket; bc++) |
1136 | { | 1093 | { |
1094 | struct PeerBucket *bucket = &k_buckets[bc]; | ||
1137 | unsigned int count = 0; | 1095 | unsigned int count = 0; |
1138 | 1096 | ||
1139 | for (struct PeerInfo *pos = k_buckets[bc].head; | 1097 | for (struct PeerInfo *pos = bucket->head; |
1140 | NULL != pos; | 1098 | NULL != pos; |
1141 | pos = pos->next) | 1099 | pos = pos->next) |
1142 | { | 1100 | { |
1143 | count++; | 1101 | count++; |
1144 | if (count > bucket_size) | 1102 | if (count > bucket_size) |
1145 | break; /* limits search to #bucket_size peers per bucket */ | 1103 | break; /* limits search to #bucket_size peers per bucket */ |
1146 | if (GNUNET_YES == | 1104 | if ( (NULL != bloom) && |
1147 | GNUNET_CONTAINER_bloomfilter_test (bloom, | 1105 | (GNUNET_YES == |
1148 | &pos->phash)) | 1106 | GNUNET_CONTAINER_bloomfilter_test (bloom, |
1107 | &pos->phash)) ) | ||
1149 | { | 1108 | { |
1150 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1109 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1151 | "Excluded peer `%s' due to BF match in random routing for %s\n", | 1110 | "Excluded peer `%s' due to BF match in random routing for %s\n", |
@@ -1180,9 +1139,10 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1180 | if (count > bucket_size) | 1139 | if (count > bucket_size) |
1181 | break; /* limits search to #bucket_size peers per bucket */ | 1140 | break; /* limits search to #bucket_size peers per bucket */ |
1182 | 1141 | ||
1183 | if (GNUNET_YES == | 1142 | if ( (NULL != bloom) && |
1184 | GNUNET_CONTAINER_bloomfilter_test (bloom, | 1143 | (GNUNET_YES == |
1185 | &pos->phash)) | 1144 | GNUNET_CONTAINER_bloomfilter_test (bloom, |
1145 | &pos->phash)) ) | ||
1186 | continue; /* Ignore bloomfiltered peers */ | 1146 | continue; /* Ignore bloomfiltered peers */ |
1187 | if (0 == selected--) | 1147 | if (0 == selected--) |
1188 | { | 1148 | { |
@@ -1296,7 +1256,7 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | |||
1296 | bd->put_path, | 1256 | bd->put_path, |
1297 | bd->put_path_length, | 1257 | bd->put_path_length, |
1298 | NULL, 0, /* get_path */ | 1258 | NULL, 0, /* get_path */ |
1299 | &my_identity)) | 1259 | &GDS_my_identity)) |
1300 | { | 1260 | { |
1301 | GNUNET_break_op (0); | 1261 | GNUNET_break_op (0); |
1302 | put_path_length = 0; | 1262 | put_path_length = 0; |
@@ -1304,10 +1264,10 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | |||
1304 | #endif | 1264 | #endif |
1305 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1265 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1306 | "Adding myself (%s) to PUT bloomfilter for %s\n", | 1266 | "Adding myself (%s) to PUT bloomfilter for %s\n", |
1307 | GNUNET_i2s (&my_identity), | 1267 | GNUNET_i2s (&GDS_my_identity), |
1308 | GNUNET_h2s (&bd->key)); | 1268 | GNUNET_h2s (&bd->key)); |
1309 | GNUNET_CONTAINER_bloomfilter_add (bf, | 1269 | GNUNET_CONTAINER_bloomfilter_add (bf, |
1310 | &my_identity_hash); | 1270 | &GDS_my_identity_hash); |
1311 | GNUNET_STATISTICS_update (GDS_stats, | 1271 | GNUNET_STATISTICS_update (GDS_stats, |
1312 | "# PUT requests routed", | 1272 | "# PUT requests routed", |
1313 | 1, | 1273 | 1, |
@@ -1324,7 +1284,7 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | |||
1324 | "Routing PUT for %s terminates after %u hops at %s\n", | 1284 | "Routing PUT for %s terminates after %u hops at %s\n", |
1325 | GNUNET_h2s (&bd->key), | 1285 | GNUNET_h2s (&bd->key), |
1326 | (unsigned int) hop_count, | 1286 | (unsigned int) hop_count, |
1327 | GNUNET_i2s (&my_identity)); | 1287 | GNUNET_i2s (&GDS_my_identity)); |
1328 | return GNUNET_NO; | 1288 | return GNUNET_NO; |
1329 | } | 1289 | } |
1330 | msize = bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement) | 1290 | msize = bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement) |
@@ -1346,30 +1306,18 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | |||
1346 | for (unsigned int i = 0; i < target_count; i++) | 1306 | for (unsigned int i = 0; i < target_count; i++) |
1347 | { | 1307 | { |
1348 | struct PeerInfo *target = targets[i]; | 1308 | struct PeerInfo *target = targets[i]; |
1349 | struct GNUNET_MQ_Envelope *env; | ||
1350 | struct PeerPutMessage *ppm; | 1309 | struct PeerPutMessage *ppm; |
1310 | char buf[sizeof (*ppm) + msize] GNUNET_ALIGN; | ||
1351 | struct GNUNET_DHT_PathElement *pp; | 1311 | struct GNUNET_DHT_PathElement *pp; |
1352 | 1312 | ||
1353 | #if FIXME_LEGACY | ||
1354 | if (GNUNET_MQ_get_length (target->mq) >= MAXIMUM_PENDING_PER_PEER) | ||
1355 | { | ||
1356 | /* skip */ | ||
1357 | GNUNET_STATISTICS_update (GDS_stats, | ||
1358 | "# P2P messages dropped due to full queue", | ||
1359 | 1, | ||
1360 | GNUNET_NO); | ||
1361 | skip_count++; | ||
1362 | continue; | ||
1363 | } | ||
1364 | #endif | ||
1365 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1313 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1366 | "Routing PUT for %s after %u hops to %s\n", | 1314 | "Routing PUT for %s after %u hops to %s\n", |
1367 | GNUNET_h2s (&bd->key), | 1315 | GNUNET_h2s (&bd->key), |
1368 | (unsigned int) hop_count, | 1316 | (unsigned int) hop_count, |
1369 | GNUNET_i2s (&target->id)); | 1317 | GNUNET_i2s (&target->id)); |
1370 | env = GNUNET_MQ_msg_extra (ppm, | 1318 | ppm = (struct PeerPutMessage *) buf; |
1371 | msize, | 1319 | ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT); |
1372 | GNUNET_MESSAGE_TYPE_DHT_P2P_PUT); | 1320 | ppm->header.size = htons (sizeof (buf)); |
1373 | ppm->options = htonl (options); | 1321 | ppm->options = htonl (options); |
1374 | ppm->type = htonl (bd->type); | 1322 | ppm->type = htonl (bd->type); |
1375 | ppm->hop_count = htonl (hop_count + 1); | 1323 | ppm->hop_count = htonl (hop_count + 1); |
@@ -1405,10 +1353,8 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | |||
1405 | GNUNET_memcpy (&pp[put_path_length], | 1353 | GNUNET_memcpy (&pp[put_path_length], |
1406 | bd->data, | 1354 | bd->data, |
1407 | bd->data_size); | 1355 | bd->data_size); |
1408 | #if FIXME | 1356 | do_send (target, |
1409 | GNUNET_MQ_send (target->mq, | 1357 | &ppm->header); |
1410 | env); | ||
1411 | #endif | ||
1412 | } | 1358 | } |
1413 | GNUNET_free (targets); | 1359 | GNUNET_free (targets); |
1414 | GNUNET_STATISTICS_update (GDS_stats, | 1360 | GNUNET_STATISTICS_update (GDS_stats, |
@@ -1450,17 +1396,17 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | |||
1450 | &targets); | 1396 | &targets); |
1451 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1397 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1452 | "Adding myself (%s) to GET bloomfilter for %s\n", | 1398 | "Adding myself (%s) to GET bloomfilter for %s\n", |
1453 | GNUNET_i2s (&my_identity), | 1399 | GNUNET_i2s (&GDS_my_identity), |
1454 | GNUNET_h2s (key)); | 1400 | GNUNET_h2s (key)); |
1455 | GNUNET_CONTAINER_bloomfilter_add (peer_bf, | 1401 | GNUNET_CONTAINER_bloomfilter_add (peer_bf, |
1456 | &my_identity_hash); | 1402 | &GDS_my_identity_hash); |
1457 | if (0 == target_count) | 1403 | if (0 == target_count) |
1458 | { | 1404 | { |
1459 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1405 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1460 | "Routing GET for %s terminates after %u hops at %s\n", | 1406 | "Routing GET for %s terminates after %u hops at %s\n", |
1461 | GNUNET_h2s (key), | 1407 | GNUNET_h2s (key), |
1462 | (unsigned int) hop_count, | 1408 | (unsigned int) hop_count, |
1463 | GNUNET_i2s (&my_identity)); | 1409 | GNUNET_i2s (&GDS_my_identity)); |
1464 | return GNUNET_NO; | 1410 | return GNUNET_NO; |
1465 | } | 1411 | } |
1466 | if (GNUNET_OK != | 1412 | if (GNUNET_OK != |
@@ -1487,30 +1433,18 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | |||
1487 | for (unsigned int i = 0; i < target_count; i++) | 1433 | for (unsigned int i = 0; i < target_count; i++) |
1488 | { | 1434 | { |
1489 | struct PeerInfo *target = targets[i]; | 1435 | struct PeerInfo *target = targets[i]; |
1490 | struct GNUNET_MQ_Envelope *env; | ||
1491 | struct PeerGetMessage *pgm; | 1436 | struct PeerGetMessage *pgm; |
1437 | char buf[sizeof (*pgm) + msize] GNUNET_ALIGN; | ||
1492 | char *xq; | 1438 | char *xq; |
1493 | 1439 | ||
1494 | #if FIXME | ||
1495 | if (GNUNET_MQ_get_length (target->mq) >= MAXIMUM_PENDING_PER_PEER) | ||
1496 | { | ||
1497 | /* skip */ | ||
1498 | GNUNET_STATISTICS_update (GDS_stats, | ||
1499 | "# P2P messages dropped due to full queue", | ||
1500 | 1, | ||
1501 | GNUNET_NO); | ||
1502 | skip_count++; | ||
1503 | continue; | ||
1504 | } | ||
1505 | #endif | ||
1506 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1440 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1507 | "Routing GET for %s after %u hops to %s\n", | 1441 | "Routing GET for %s after %u hops to %s\n", |
1508 | GNUNET_h2s (key), | 1442 | GNUNET_h2s (key), |
1509 | (unsigned int) hop_count, | 1443 | (unsigned int) hop_count, |
1510 | GNUNET_i2s (&target->id)); | 1444 | GNUNET_i2s (&target->id)); |
1511 | env = GNUNET_MQ_msg_extra (pgm, | 1445 | pgm = (struct PeerGetMessage *) buf; |
1512 | msize, | 1446 | pgm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET); |
1513 | GNUNET_MESSAGE_TYPE_DHT_P2P_GET); | 1447 | pgm->header.size = htons (sizeof (buf)); |
1514 | pgm->options = htonl (options); | 1448 | pgm->options = htonl (options); |
1515 | pgm->type = htonl (type); | 1449 | pgm->type = htonl (type); |
1516 | pgm->hop_count = htonl (hop_count + 1); | 1450 | pgm->hop_count = htonl (hop_count + 1); |
@@ -1532,10 +1466,8 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | |||
1532 | GNUNET_memcpy (&xq[xquery_size], | 1466 | GNUNET_memcpy (&xq[xquery_size], |
1533 | reply_bf, | 1467 | reply_bf, |
1534 | reply_bf_size); | 1468 | reply_bf_size); |
1535 | #if FIXME | 1469 | do_send (target, |
1536 | GNUNET_MQ_send (target->mq, | 1470 | &pgm->header); |
1537 | env); | ||
1538 | #endif | ||
1539 | } | 1471 | } |
1540 | GNUNET_STATISTICS_update (GDS_stats, | 1472 | GNUNET_STATISTICS_update (GDS_stats, |
1541 | "# GET messages queued for transmission", | 1473 | "# GET messages queued for transmission", |
@@ -1562,8 +1494,6 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, | |||
1562 | unsigned int get_path_length, | 1494 | unsigned int get_path_length, |
1563 | const struct GNUNET_DHT_PathElement *get_path) | 1495 | const struct GNUNET_DHT_PathElement *get_path) |
1564 | { | 1496 | { |
1565 | struct GNUNET_MQ_Envelope *env; | ||
1566 | struct PeerResultMessage *prm; | ||
1567 | struct GNUNET_DHT_PathElement *paths; | 1497 | struct GNUNET_DHT_PathElement *paths; |
1568 | size_t msize; | 1498 | size_t msize; |
1569 | unsigned int ppl = bd->put_path_length; | 1499 | unsigned int ppl = bd->put_path_length; |
@@ -1578,7 +1508,7 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, | |||
1578 | bd->put_path_length, | 1508 | bd->put_path_length, |
1579 | get_path, | 1509 | get_path, |
1580 | get_path_length, | 1510 | get_path_length, |
1581 | &my_identity)) | 1511 | &GDS_my_identity)) |
1582 | { | 1512 | { |
1583 | GNUNET_break_op (0); | 1513 | GNUNET_break_op (0); |
1584 | get_path_length = 0; | 1514 | get_path_length = 0; |
@@ -1609,20 +1539,6 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, | |||
1609 | GNUNET_break (0); | 1539 | GNUNET_break (0); |
1610 | return; | 1540 | return; |
1611 | } | 1541 | } |
1612 | #if FIXME | ||
1613 | if (GNUNET_MQ_get_length (pi->mq) >= MAXIMUM_PENDING_PER_PEER) | ||
1614 | { | ||
1615 | /* skip */ | ||
1616 | GNUNET_STATISTICS_update (GDS_stats, | ||
1617 | "# P2P messages dropped due to full queue", | ||
1618 | 1, | ||
1619 | GNUNET_NO); | ||
1620 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1621 | "Peer queue full, ignoring reply for key %s\n", | ||
1622 | GNUNET_h2s (&bd->key)); | ||
1623 | return; | ||
1624 | } | ||
1625 | #endif | ||
1626 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1542 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1627 | "Forwarding reply for key %s to peer %s\n", | 1543 | "Forwarding reply for key %s to peer %s\n", |
1628 | GNUNET_h2s (query_hash), | 1544 | GNUNET_h2s (query_hash), |
@@ -1631,41 +1547,44 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, | |||
1631 | "# RESULT messages queued for transmission", | 1547 | "# RESULT messages queued for transmission", |
1632 | 1, | 1548 | 1, |
1633 | GNUNET_NO); | 1549 | GNUNET_NO); |
1634 | env = GNUNET_MQ_msg_extra (prm, | ||
1635 | msize, | ||
1636 | GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT); | ||
1637 | prm->type = htonl (bd->type); | ||
1638 | prm->put_path_length = htonl (ppl); | ||
1639 | prm->get_path_length = htonl (get_path_length); | ||
1640 | prm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); | ||
1641 | prm->key = *query_hash; | ||
1642 | paths = (struct GNUNET_DHT_PathElement *) &prm[1]; | ||
1643 | GNUNET_memcpy (paths, | ||
1644 | bd->put_path, | ||
1645 | ppl * sizeof(struct GNUNET_DHT_PathElement)); | ||
1646 | GNUNET_memcpy (&paths[ppl], | ||
1647 | get_path, | ||
1648 | get_path_length * sizeof(struct GNUNET_DHT_PathElement)); | ||
1649 | /* 0 == get_path_length means path is not being tracked */ | ||
1650 | if (0 != get_path_length) | ||
1651 | { | 1550 | { |
1652 | /* Note that the signature in 'get_path' was not initialized before, | 1551 | struct PeerResultMessage *prm; |
1653 | so this is crucial to avoid sending garbage. */ | 1552 | char buf[sizeof (*prm) + msize] GNUNET_ALIGN; |
1654 | sign_path (&bd->key, | 1553 | |
1655 | bd->data, | 1554 | prm = (struct PeerResultMessage *) buf; |
1656 | bd->data_size, | 1555 | prm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT); |
1657 | bd->expiration_time, | 1556 | prm->header.size = htons (sizeof (buf)); |
1658 | &paths[ppl + get_path_length - 1].pred, | 1557 | prm->type = htonl (bd->type); |
1659 | &pi->id, | 1558 | prm->put_path_length = htonl (ppl); |
1660 | &paths[ppl + get_path_length - 1].sig); | 1559 | prm->get_path_length = htonl (get_path_length); |
1661 | } | 1560 | prm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); |
1662 | GNUNET_memcpy (&paths[ppl + get_path_length], | 1561 | prm->key = *query_hash; |
1562 | paths = (struct GNUNET_DHT_PathElement *) &prm[1]; | ||
1563 | GNUNET_memcpy (paths, | ||
1564 | bd->put_path, | ||
1565 | ppl * sizeof(struct GNUNET_DHT_PathElement)); | ||
1566 | GNUNET_memcpy (&paths[ppl], | ||
1567 | get_path, | ||
1568 | get_path_length * sizeof(struct GNUNET_DHT_PathElement)); | ||
1569 | /* 0 == get_path_length means path is not being tracked */ | ||
1570 | if (0 != get_path_length) | ||
1571 | { | ||
1572 | /* Note that the signature in 'get_path' was not initialized before, | ||
1573 | so this is crucial to avoid sending garbage. */ | ||
1574 | sign_path (&bd->key, | ||
1663 | bd->data, | 1575 | bd->data, |
1664 | bd->data_size); | 1576 | bd->data_size, |
1665 | #if FIXME | 1577 | bd->expiration_time, |
1666 | GNUNET_MQ_send (pi->mq, | 1578 | &paths[ppl + get_path_length - 1].pred, |
1667 | env); | 1579 | &pi->id, |
1668 | #endif | 1580 | &paths[ppl + get_path_length - 1].sig); |
1581 | } | ||
1582 | GNUNET_memcpy (&paths[ppl + get_path_length], | ||
1583 | bd->data, | ||
1584 | bd->data_size); | ||
1585 | do_send (pi, | ||
1586 | &prm->header); | ||
1587 | } | ||
1669 | } | 1588 | } |
1670 | 1589 | ||
1671 | 1590 | ||
@@ -1819,7 +1738,7 @@ handle_dht_p2p_put (void *cls, | |||
1819 | bd.put_path, | 1738 | bd.put_path, |
1820 | putlen, | 1739 | putlen, |
1821 | NULL, 0, /* get_path */ | 1740 | NULL, 0, /* get_path */ |
1822 | &my_identity)) | 1741 | &GDS_my_identity)) |
1823 | { | 1742 | { |
1824 | GNUNET_break_op (0); | 1743 | GNUNET_break_op (0); |
1825 | putlen = 0; | 1744 | putlen = 0; |
@@ -1875,45 +1794,60 @@ handle_dht_p2p_put (void *cls, | |||
1875 | 1794 | ||
1876 | 1795 | ||
1877 | /** | 1796 | /** |
1878 | * We have received a FIND PEER request. Send matching | 1797 | * We have received a request for a HELLO. Sends our |
1879 | * HELLOs back. | 1798 | * HELLO back. |
1880 | * | 1799 | * |
1881 | * @param pi sender of the FIND PEER request | 1800 | * @param pi sender of the request |
1882 | * @param key peers close to this key are desired | 1801 | * @param key peers close to this key are desired |
1883 | * @param bg group for filtering peers | 1802 | * @param bg group for filtering peers |
1884 | */ | 1803 | */ |
1885 | static void | 1804 | static void |
1886 | handle_find_peer (struct PeerInfo *pi, | 1805 | handle_find_my_hello (struct PeerInfo *pi, |
1887 | const struct GNUNET_HashCode *query_hash, | 1806 | const struct GNUNET_HashCode *query_hash, |
1888 | struct GNUNET_BLOCK_Group *bg) | 1807 | struct GNUNET_BLOCK_Group *bg) |
1889 | { | 1808 | { |
1890 | int bucket_idx; | 1809 | size_t block_size = 0; |
1891 | struct PeerBucket *bucket; | 1810 | |
1892 | struct PeerInfo *peer; | 1811 | /* TODO: consider caching our HELLO block for a bit, to |
1893 | unsigned int choice; | 1812 | avoid signing too often here... */ |
1894 | struct GDS_DATACACHE_BlockData bd = { | 1813 | GNUNET_break (GNUNET_NO == |
1895 | .type = GNUNET_BLOCK_TYPE_DHT_URL_HELLO | 1814 | GNUNET_HELLO_builder_to_block (GDS_my_hello, |
1896 | }; | 1815 | &GDS_my_private_key, |
1897 | 1816 | NULL, | |
1898 | /* first, check about our own HELLO */ | 1817 | &block_size)); |
1899 | if (NULL != GDS_my_hello) | ||
1900 | { | 1818 | { |
1901 | bd.expiration_time = GNUNET_TIME_relative_to_absolute ( | 1819 | char block[block_size]; |
1902 | hello_expiration), | 1820 | |
1903 | bd.key = my_identity_hash, | 1821 | if (GNUNET_OK != |
1904 | bd.data = GDS_my_hello; | 1822 | GNUNET_HELLO_builder_to_block (GDS_my_hello, |
1905 | bd.data_size = GNUNET_HELLO_size ( | 1823 | &GDS_my_private_key, |
1906 | (const struct GNUNET_HELLO_Message *) GDS_my_hello); | 1824 | block, |
1907 | GNUNET_break (bd.data_size >= sizeof(struct GNUNET_MessageHeader)); | 1825 | &block_size)) |
1908 | if (GNUNET_BLOCK_REPLY_OK_MORE == | ||
1909 | GNUNET_BLOCK_check_reply (GDS_block_context, | ||
1910 | GNUNET_BLOCK_TYPE_DHT_URL_HELLO, | ||
1911 | bg, | ||
1912 | &my_identity_hash, | ||
1913 | NULL, 0, | ||
1914 | bd.data, | ||
1915 | bd.data_size)) | ||
1916 | { | 1826 | { |
1827 | GNUNET_STATISTICS_update (GDS_stats, | ||
1828 | "# FIND PEER requests ignored due to lack of HELLO", | ||
1829 | 1, | ||
1830 | GNUNET_NO); | ||
1831 | } | ||
1832 | else if (GNUNET_BLOCK_REPLY_OK_MORE == | ||
1833 | GNUNET_BLOCK_check_reply (GDS_block_context, | ||
1834 | GNUNET_BLOCK_TYPE_DHT_URL_HELLO, | ||
1835 | bg, | ||
1836 | &GDS_my_identity_hash, | ||
1837 | NULL, 0, | ||
1838 | block, | ||
1839 | block_size)) | ||
1840 | { | ||
1841 | struct GDS_DATACACHE_BlockData bd = { | ||
1842 | .type = GNUNET_BLOCK_TYPE_DHT_URL_HELLO, | ||
1843 | .expiration_time | ||
1844 | = GNUNET_TIME_relative_to_absolute ( | ||
1845 | GNUNET_HELLO_ADDRESS_EXPIRATION), | ||
1846 | .key = GDS_my_identity_hash, | ||
1847 | .data = block, | ||
1848 | .data_size = block_size | ||
1849 | }; | ||
1850 | |||
1917 | GDS_NEIGHBOURS_handle_reply (pi, | 1851 | GDS_NEIGHBOURS_handle_reply (pi, |
1918 | &bd, | 1852 | &bd, |
1919 | query_hash, | 1853 | query_hash, |
@@ -1927,66 +1861,48 @@ handle_find_peer (struct PeerInfo *pi, | |||
1927 | GNUNET_NO); | 1861 | GNUNET_NO); |
1928 | } | 1862 | } |
1929 | } | 1863 | } |
1930 | else | 1864 | } |
1931 | { | ||
1932 | GNUNET_STATISTICS_update (GDS_stats, | ||
1933 | "# FIND PEER requests ignored due to lack of HELLO", | ||
1934 | 1, | ||
1935 | GNUNET_NO); | ||
1936 | } | ||
1937 | 1865 | ||
1938 | /* then, also consider sending a random HELLO from the closest bucket */ | ||
1939 | /* FIXME: How can this be true? Shouldnt we just do find_bucket() ? */ | ||
1940 | if (0 == | ||
1941 | GNUNET_memcmp (&my_identity_hash, | ||
1942 | query_hash)) | ||
1943 | bucket_idx = closest_bucket - 1; | ||
1944 | else | ||
1945 | bucket_idx = GNUNET_MIN ((int) closest_bucket - 1, | ||
1946 | find_bucket (query_hash)); | ||
1947 | if (bucket_idx < 0) | ||
1948 | return; | ||
1949 | bucket = &k_buckets[bucket_idx]; | ||
1950 | if (bucket->peers_size == 0) | ||
1951 | return; | ||
1952 | choice = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
1953 | bucket->peers_size); | ||
1954 | peer = bucket->head; | ||
1955 | while (choice > 0) | ||
1956 | { | ||
1957 | GNUNET_assert (NULL != peer); | ||
1958 | peer = peer->next; | ||
1959 | choice--; | ||
1960 | } | ||
1961 | choice = bucket->peers_size; | ||
1962 | 1866 | ||
1867 | /** | ||
1868 | * We have received a request for nearby HELLOs. Sends matching | ||
1869 | * HELLOs back. | ||
1870 | * | ||
1871 | * @param pi sender of the request | ||
1872 | * @param key peers close to this key are desired | ||
1873 | * @param bg group for filtering peers | ||
1874 | */ | ||
1875 | static void | ||
1876 | handle_find_local_hello (struct PeerInfo *pi, | ||
1877 | const struct GNUNET_HashCode *query_hash, | ||
1878 | struct GNUNET_BLOCK_Group *bg) | ||
1879 | { | ||
1880 | /* Force non-random selection by hop count */ | ||
1881 | struct PeerInfo *peer; | ||
1882 | |||
1883 | peer = select_peer (query_hash, | ||
1884 | NULL, | ||
1885 | GDS_NSE_get () + 1); | ||
1886 | if ( (NULL != peer->hello) && | ||
1887 | (! GNUNET_TIME_absolute_is_past (peer->hello_expiration)) && | ||
1888 | (GNUNET_BLOCK_REPLY_OK_MORE == | ||
1889 | GNUNET_BLOCK_check_reply ( | ||
1890 | GDS_block_context, | ||
1891 | GNUNET_BLOCK_TYPE_DHT_URL_HELLO, | ||
1892 | bg, | ||
1893 | &peer->phash, | ||
1894 | NULL, 0, /* xquery */ | ||
1895 | peer->hello, | ||
1896 | peer->hello_size)) ) | ||
1963 | { | 1897 | { |
1964 | const struct GNUNET_HELLO_Message *hello; | 1898 | struct GDS_DATACACHE_BlockData bd = { |
1965 | size_t hello_size; | 1899 | .type = GNUNET_BLOCK_TYPE_DHT_URL_HELLO, |
1900 | .expiration_time = peer->hello_expiration, | ||
1901 | .key = peer->phash, | ||
1902 | .data = peer->hello, | ||
1903 | .data_size = peer->hello_size | ||
1904 | }; | ||
1966 | 1905 | ||
1967 | do | ||
1968 | { | ||
1969 | peer = peer->next; | ||
1970 | if (0 == choice--) | ||
1971 | return; /* no non-masked peer available */ | ||
1972 | if (NULL == peer) | ||
1973 | peer = bucket->head; | ||
1974 | hello = GDS_HELLO_get (&peer->id); | ||
1975 | } while ( (NULL == hello) || | ||
1976 | (GNUNET_BLOCK_REPLY_OK_MORE != | ||
1977 | GNUNET_BLOCK_check_reply ( | ||
1978 | GDS_block_context, | ||
1979 | GNUNET_BLOCK_TYPE_DHT_URL_HELLO, | ||
1980 | bg, | ||
1981 | &peer->phash, | ||
1982 | NULL, 0, /* xquery */ | ||
1983 | hello, | ||
1984 | (hello_size = GNUNET_HELLO_size (hello))))); | ||
1985 | bd.expiration_time = GNUNET_TIME_relative_to_absolute ( | ||
1986 | GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION); | ||
1987 | bd.key = peer->phash; | ||
1988 | bd.data = hello; | ||
1989 | bd.data_size = hello_size; | ||
1990 | GDS_NEIGHBOURS_handle_reply (pi, | 1906 | GDS_NEIGHBOURS_handle_reply (pi, |
1991 | &bd, | 1907 | &bd, |
1992 | query_hash, | 1908 | query_hash, |
@@ -2101,32 +2017,45 @@ handle_dht_p2p_get (void *cls, | |||
2101 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2017 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2102 | "GET for %s at %s after %u hops\n", | 2018 | "GET for %s at %s after %u hops\n", |
2103 | GNUNET_h2s (&get->key), | 2019 | GNUNET_h2s (&get->key), |
2104 | GNUNET_i2s (&my_identity), | 2020 | GNUNET_i2s (&GDS_my_identity), |
2105 | (unsigned int) hop_count); | 2021 | (unsigned int) hop_count); |
2106 | /* local lookup (this may update the reply_bf) */ | 2022 | /* local lookup (this may update the bg) */ |
2107 | if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || | 2023 | if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || |
2108 | (GDS_am_closest_peer (&get->key, | 2024 | (GDS_am_closest_peer (&get->key, |
2109 | peer_bf)) ) | 2025 | peer_bf)) ) |
2110 | { | 2026 | { |
2111 | if ((0 != (options & GNUNET_DHT_RO_FIND_PEER))) | 2027 | if (GNUNET_BLOCK_TYPE_DHT_URL_HELLO == type) |
2112 | { | 2028 | { |
2113 | GNUNET_STATISTICS_update (GDS_stats, | 2029 | GNUNET_STATISTICS_update (GDS_stats, |
2114 | "# P2P FIND PEER requests processed", | 2030 | "# P2P HELLO lookup requests processed", |
2115 | 1, | 2031 | 1, |
2116 | GNUNET_NO); | 2032 | GNUNET_NO); |
2117 | handle_find_peer (peer, | 2033 | handle_find_my_hello (peer, |
2118 | &get->key, | 2034 | &get->key, |
2119 | bg); | 2035 | bg); |
2036 | if (0 != (options & GNUNET_DHT_RO_FIND_APPROXIMATE)) | ||
2037 | handle_find_local_hello (peer, | ||
2038 | &get->key, | ||
2039 | bg); | ||
2120 | } | 2040 | } |
2121 | else | 2041 | else |
2122 | { | 2042 | { |
2123 | eval = GDS_DATACACHE_handle_get (&get->key, | 2043 | if (0 != (options & GNUNET_DHT_RO_FIND_APPROXIMATE)) |
2124 | type, | 2044 | eval = GDS_DATACACHE_get_closest (&get->key, |
2125 | xquery, | 2045 | type, |
2126 | xquery_size, | 2046 | xquery, |
2127 | bg, | 2047 | xquery_size, |
2128 | &handle_local_result, | 2048 | bg, |
2129 | peer); | 2049 | &handle_local_result, |
2050 | peer); | ||
2051 | else | ||
2052 | eval = GDS_DATACACHE_handle_get (&get->key, | ||
2053 | type, | ||
2054 | xquery, | ||
2055 | xquery_size, | ||
2056 | bg, | ||
2057 | &handle_local_result, | ||
2058 | peer); | ||
2130 | } | 2059 | } |
2131 | } | 2060 | } |
2132 | else | 2061 | else |
@@ -2137,7 +2066,9 @@ handle_dht_p2p_get (void *cls, | |||
2137 | GNUNET_NO); | 2066 | GNUNET_NO); |
2138 | } | 2067 | } |
2139 | 2068 | ||
2140 | /* remember request for routing replies */ | 2069 | /* remember request for routing replies |
2070 | TODO: why should we do this if GNUNET_BLOCK_REPLY_OK_LAST == eval? | ||
2071 | */ | ||
2141 | GDS_ROUTING_add (&peer->id, | 2072 | GDS_ROUTING_add (&peer->id, |
2142 | type, | 2073 | type, |
2143 | bg, /* bg now owned by routing, but valid at least until end of this function! */ | 2074 | bg, /* bg now owned by routing, but valid at least until end of this function! */ |
@@ -2260,6 +2191,52 @@ check_dht_p2p_result (void *cls, | |||
2260 | 2191 | ||
2261 | 2192 | ||
2262 | /** | 2193 | /** |
2194 | * Callback function used to extract URIs from a builder. | ||
2195 | * Called when we should consider connecting to a peer. | ||
2196 | * | ||
2197 | * @param cls closure pointing to a `struct GNUNET_PeerIdentity *` | ||
2198 | * @param uri one of the URIs | ||
2199 | */ | ||
2200 | static void | ||
2201 | try_connect (void *cls, | ||
2202 | const char *uri) | ||
2203 | { | ||
2204 | const struct GNUNET_PeerIdentity *pid = cls; | ||
2205 | struct GNUNET_HashCode phash; | ||
2206 | int peer_bucket; | ||
2207 | struct PeerBucket *bucket; | ||
2208 | |||
2209 | if (0 == GNUNET_memcmp (&GDS_my_identity, | ||
2210 | pid)) | ||
2211 | return; /* that's us! */ | ||
2212 | GNUNET_CRYPTO_hash (pid, | ||
2213 | sizeof(*pid), | ||
2214 | &phash); | ||
2215 | peer_bucket = find_bucket (&phash); | ||
2216 | GNUNET_assert ( (peer_bucket >= 0) && | ||
2217 | ((unsigned int) peer_bucket < MAX_BUCKETS)); | ||
2218 | bucket = &k_buckets[peer_bucket]; | ||
2219 | if (bucket->peers_size >= bucket_size) | ||
2220 | return; /* do not care */ | ||
2221 | for (struct PeerInfo *pi = bucket->head; | ||
2222 | NULL != pi; | ||
2223 | pi = pi->next) | ||
2224 | if (0 == | ||
2225 | GNUNET_memcmp (&pi->id, | ||
2226 | pid)) | ||
2227 | { | ||
2228 | /* already connected */ | ||
2229 | /* TODO: maybe consider 'uri' anyway as an additional | ||
2230 | alternative address??? */ | ||
2231 | return; | ||
2232 | } | ||
2233 | /* new peer that we like! */ | ||
2234 | GDS_u_try_connect (pid, | ||
2235 | uri); | ||
2236 | } | ||
2237 | |||
2238 | |||
2239 | /** | ||
2263 | * Core handler for p2p result messages. | 2240 | * Core handler for p2p result messages. |
2264 | * | 2241 | * |
2265 | * @param cls closure | 2242 | * @param cls closure |
@@ -2333,32 +2310,17 @@ handle_dht_p2p_result (void *cls, | |||
2333 | /* if we got a HELLO, consider it for our own routing table */ | 2310 | /* if we got a HELLO, consider it for our own routing table */ |
2334 | if (GNUNET_BLOCK_TYPE_DHT_URL_HELLO == bd.type) | 2311 | if (GNUNET_BLOCK_TYPE_DHT_URL_HELLO == bd.type) |
2335 | { | 2312 | { |
2336 | const struct GNUNET_MessageHeader *h = bd.data; | ||
2337 | struct GNUNET_PeerIdentity pid; | 2313 | struct GNUNET_PeerIdentity pid; |
2338 | 2314 | struct GNUNET_HELLO_Builder *b; | |
2339 | /* Should be a HELLO, validate and consider using it! */ | 2315 | |
2340 | if (bd.data_size < sizeof(struct GNUNET_HELLO_Message)) | 2316 | b = GNUNET_HELLO_builder_from_block (bd.data, |
2341 | { | 2317 | bd.data_size); |
2342 | GNUNET_break (0); | 2318 | if (GNUNET_YES != disable_try_connect) |
2343 | return; | 2319 | GNUNET_HELLO_builder_iterate (b, |
2344 | } | 2320 | &pid, |
2345 | if (bd.data_size != ntohs (h->size)) | 2321 | &try_connect, |
2346 | { | 2322 | &pid); |
2347 | GNUNET_break (0); | 2323 | GNUNET_HELLO_builder_free (b); |
2348 | return; | ||
2349 | } | ||
2350 | if (GNUNET_OK != | ||
2351 | GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) h, | ||
2352 | &pid)) | ||
2353 | { | ||
2354 | GNUNET_break_op (0); | ||
2355 | return; | ||
2356 | } | ||
2357 | if ( (GNUNET_YES != disable_try_connect) && | ||
2358 | (0 != GNUNET_memcmp (&my_identity, | ||
2359 | &pid)) ) | ||
2360 | try_connect (&pid, | ||
2361 | h); | ||
2362 | } | 2324 | } |
2363 | 2325 | ||
2364 | /* First, check if 'peer' is already on the path, and if | 2326 | /* First, check if 'peer' is already on the path, and if |
@@ -2391,6 +2353,50 @@ handle_dht_p2p_result (void *cls, | |||
2391 | } | 2353 | } |
2392 | 2354 | ||
2393 | 2355 | ||
2356 | /** | ||
2357 | * Check validity of a p2p hello message. | ||
2358 | * | ||
2359 | * @param cls closure | ||
2360 | * @param hello message | ||
2361 | * @return #GNUNET_YES if the message is well-formed | ||
2362 | */ | ||
2363 | static enum GNUNET_GenericReturnValue | ||
2364 | check_dht_p2p_hello (void *cls, | ||
2365 | const struct GNUNET_MessageHeader *hello) | ||
2366 | { | ||
2367 | struct GNUNET_HELLO_Builder *b; | ||
2368 | enum GNUNET_GenericReturnValue ret; | ||
2369 | |||
2370 | b = GNUNET_HELLO_builder_from_msg (hello); | ||
2371 | ret = (NULL == b) ? GNUNET_SYSERR : GNUNET_OK; | ||
2372 | GNUNET_HELLO_builder_free (b); | ||
2373 | return ret; | ||
2374 | } | ||
2375 | |||
2376 | |||
2377 | /** | ||
2378 | * Core handler for p2p HELLO messages. | ||
2379 | * | ||
2380 | * @param cls closure | ||
2381 | * @param message message | ||
2382 | */ | ||
2383 | static void | ||
2384 | handle_dht_p2p_hello (void *cls, | ||
2385 | const struct GNUNET_MessageHeader *hello) | ||
2386 | { | ||
2387 | struct PeerInfo *peer = cls; | ||
2388 | |||
2389 | GNUNET_free (peer->hello); | ||
2390 | peer->hello_size = 0; | ||
2391 | GNUNET_break (GNUNET_OK == | ||
2392 | GNUNET_HELLO_dht_msg_to_block (hello, | ||
2393 | &peer->id, | ||
2394 | &peer->hello, | ||
2395 | &peer->hello_size, | ||
2396 | &peer->hello_expiration)); | ||
2397 | } | ||
2398 | |||
2399 | |||
2394 | void | 2400 | void |
2395 | GDS_u_receive (void *cls, | 2401 | GDS_u_receive (void *cls, |
2396 | void **tctx, | 2402 | void **tctx, |
@@ -2412,6 +2418,10 @@ GDS_u_receive (void *cls, | |||
2412 | GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT, | 2418 | GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT, |
2413 | struct PeerResultMessage, | 2419 | struct PeerResultMessage, |
2414 | pi), | 2420 | pi), |
2421 | GNUNET_MQ_hd_var_size (dht_p2p_hello, | ||
2422 | GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO, | ||
2423 | struct GNUNET_MessageHeader, | ||
2424 | pi), | ||
2415 | GNUNET_MQ_handler_end () | 2425 | GNUNET_MQ_handler_end () |
2416 | }; | 2426 | }; |
2417 | const struct GNUNET_MessageHeader *mh = message; | 2427 | const struct GNUNET_MessageHeader *mh = message; |
@@ -2438,6 +2448,34 @@ GDS_u_receive (void *cls, | |||
2438 | } | 2448 | } |
2439 | 2449 | ||
2440 | 2450 | ||
2451 | /** | ||
2452 | * Send @a msg to all peers in our buckets. | ||
2453 | * | ||
2454 | * @param msg message to broadcast | ||
2455 | */ | ||
2456 | void | ||
2457 | GDS_NEIGHBOURS_broadcast (const struct GNUNET_MessageHeader *msg) | ||
2458 | { | ||
2459 | for (unsigned int bc = 0; bc<closest_bucket; bc++) | ||
2460 | { | ||
2461 | struct PeerBucket *bucket = &k_buckets[bc]; | ||
2462 | unsigned int count = 0; | ||
2463 | |||
2464 | for (struct PeerInfo *pos = bucket->head; | ||
2465 | NULL != pos; | ||
2466 | pos = pos->next) | ||
2467 | { | ||
2468 | if (count >= bucket_size) | ||
2469 | break; /* we only consider first #bucket_size entries per bucket */ | ||
2470 | count++; | ||
2471 | GNUNET_break (0); | ||
2472 | do_send (pos, | ||
2473 | msg); | ||
2474 | } | ||
2475 | } | ||
2476 | } | ||
2477 | |||
2478 | |||
2441 | enum GNUNET_GenericReturnValue | 2479 | enum GNUNET_GenericReturnValue |
2442 | GDS_NEIGHBOURS_init () | 2480 | GDS_NEIGHBOURS_init () |
2443 | { | 2481 | { |
@@ -2458,41 +2496,8 @@ GDS_NEIGHBOURS_init () | |||
2458 | = GNUNET_CONFIGURATION_get_value_yesno (GDS_cfg, | 2496 | = GNUNET_CONFIGURATION_get_value_yesno (GDS_cfg, |
2459 | "DHT", | 2497 | "DHT", |
2460 | "CACHE_RESULTS"); | 2498 | "CACHE_RESULTS"); |
2461 | { | ||
2462 | char *keyfile; | ||
2463 | |||
2464 | if (GNUNET_OK != | ||
2465 | GNUNET_CONFIGURATION_get_value_filename (GDS_cfg, | ||
2466 | "PEER", | ||
2467 | "PRIVATE_KEY", | ||
2468 | &keyfile)) | ||
2469 | { | ||
2470 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2471 | "Core service is lacking HOSTKEY configuration setting. Exiting.\n"); | ||
2472 | return GNUNET_SYSERR; | ||
2473 | } | ||
2474 | if (GNUNET_SYSERR == | ||
2475 | GNUNET_CRYPTO_eddsa_key_from_file (keyfile, | ||
2476 | GNUNET_YES, | ||
2477 | &my_private_key)) | ||
2478 | { | ||
2479 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2480 | "Failed to setup peer's private key\n"); | ||
2481 | GNUNET_free (keyfile); | ||
2482 | return GNUNET_SYSERR; | ||
2483 | } | ||
2484 | GNUNET_free (keyfile); | ||
2485 | } | ||
2486 | GNUNET_CRYPTO_eddsa_key_get_public (&my_private_key, | ||
2487 | &my_identity.public_key); | ||
2488 | GNUNET_CRYPTO_hash (&my_identity, | ||
2489 | sizeof(struct GNUNET_PeerIdentity), | ||
2490 | &my_identity_hash); | ||
2491 | |||
2492 | all_connected_peers = GNUNET_CONTAINER_multipeermap_create (256, | 2499 | all_connected_peers = GNUNET_CONTAINER_multipeermap_create (256, |
2493 | GNUNET_YES); | 2500 | GNUNET_YES); |
2494 | all_desired_peers = GNUNET_CONTAINER_multipeermap_create (256, | ||
2495 | GNUNET_NO); | ||
2496 | return GNUNET_OK; | 2501 | return GNUNET_OK; |
2497 | } | 2502 | } |
2498 | 2503 | ||
@@ -2506,11 +2511,6 @@ GDS_NEIGHBOURS_done () | |||
2506 | GNUNET_CONTAINER_multipeermap_size (all_connected_peers)); | 2511 | GNUNET_CONTAINER_multipeermap_size (all_connected_peers)); |
2507 | GNUNET_CONTAINER_multipeermap_destroy (all_connected_peers); | 2512 | GNUNET_CONTAINER_multipeermap_destroy (all_connected_peers); |
2508 | all_connected_peers = NULL; | 2513 | all_connected_peers = NULL; |
2509 | GNUNET_CONTAINER_multipeermap_iterate (all_desired_peers, | ||
2510 | &free_connect_info, | ||
2511 | NULL); | ||
2512 | GNUNET_CONTAINER_multipeermap_destroy (all_desired_peers); | ||
2513 | all_desired_peers = NULL; | ||
2514 | GNUNET_assert (NULL == find_peer_task); | 2514 | GNUNET_assert (NULL == find_peer_task); |
2515 | } | 2515 | } |
2516 | 2516 | ||
@@ -2518,7 +2518,7 @@ GDS_NEIGHBOURS_done () | |||
2518 | struct GNUNET_PeerIdentity * | 2518 | struct GNUNET_PeerIdentity * |
2519 | GDS_NEIGHBOURS_get_id () | 2519 | GDS_NEIGHBOURS_get_id () |
2520 | { | 2520 | { |
2521 | return &my_identity; | 2521 | return &GDS_my_identity; |
2522 | } | 2522 | } |
2523 | 2523 | ||
2524 | 2524 | ||
diff --git a/src/dht/gnunet-service-dht_neighbours.h b/src/dht/gnunet-service-dht_neighbours.h index e1a553f06..5a4c8c620 100644 --- a/src/dht/gnunet-service-dht_neighbours.h +++ b/src/dht/gnunet-service-dht_neighbours.h | |||
@@ -33,11 +33,6 @@ | |||
33 | #include "gnunet_dhtu_plugin.h" | 33 | #include "gnunet_dhtu_plugin.h" |
34 | #include "gnunet-service-dht_datacache.h" | 34 | #include "gnunet-service-dht_datacache.h" |
35 | 35 | ||
36 | /** | ||
37 | * Hash of the identity of this peer. | ||
38 | */ | ||
39 | extern struct GNUNET_HashCode my_identity_hash; | ||
40 | |||
41 | 36 | ||
42 | struct PeerInfo; | 37 | struct PeerInfo; |
43 | 38 | ||
@@ -141,7 +136,7 @@ GDS_am_closest_peer (const struct GNUNET_HashCode *key, | |||
141 | * Function to call when we connect to a peer and can henceforth transmit to | 136 | * Function to call when we connect to a peer and can henceforth transmit to |
142 | * that peer. | 137 | * that peer. |
143 | * | 138 | * |
144 | * @param cls the closure | 139 | * @param cls the closure, must be a `struct Underlay` |
145 | * @param target handle to the target, | 140 | * @param target handle to the target, |
146 | * pointer will remain valid until @e disconnect_cb is called | 141 | * pointer will remain valid until @e disconnect_cb is called |
147 | * @para pid peer identity, | 142 | * @para pid peer identity, |
@@ -154,6 +149,7 @@ GDS_u_connect (void *cls, | |||
154 | const struct GNUNET_PeerIdentity *pid, | 149 | const struct GNUNET_PeerIdentity *pid, |
155 | void **ctx); | 150 | void **ctx); |
156 | 151 | ||
152 | |||
157 | /** | 153 | /** |
158 | * Function to call when we disconnected from a peer and can henceforth | 154 | * Function to call when we disconnected from a peer and can henceforth |
159 | * cannot transmit to that peer anymore. | 155 | * cannot transmit to that peer anymore. |
@@ -183,6 +179,15 @@ GDS_u_receive (void *cls, | |||
183 | 179 | ||
184 | 180 | ||
185 | /** | 181 | /** |
182 | * Send @a msg to all peers in our buckets. | ||
183 | * | ||
184 | * @param msg message to broadcast | ||
185 | */ | ||
186 | void | ||
187 | GDS_NEIGHBOURS_broadcast (const struct GNUNET_MessageHeader *msg); | ||
188 | |||
189 | |||
190 | /** | ||
186 | * Initialize neighbours subsystem. | 191 | * Initialize neighbours subsystem. |
187 | * | 192 | * |
188 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 193 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c index e7b5c3571..ec3f5b46f 100644 --- a/src/dht/gnunet-service-dht_routing.c +++ b/src/dht/gnunet-service-dht_routing.c | |||
@@ -151,7 +151,7 @@ process (void *cls, | |||
151 | bdx.put_path_length = 0; | 151 | bdx.put_path_length = 0; |
152 | bdx.put_path = NULL; | 152 | bdx.put_path = NULL; |
153 | } | 153 | } |
154 | if ( (0 == (rr->options & GNUNET_DHT_RO_FIND_PEER)) && | 154 | if ( (0 == (rr->options & GNUNET_DHT_RO_FIND_APPROXIMATE)) && |
155 | (0 != GNUNET_memcmp (query_hash, | 155 | (0 != GNUNET_memcmp (query_hash, |
156 | &bdx.key)) ) | 156 | &bdx.key)) ) |
157 | { | 157 | { |