diff options
Diffstat (limited to 'src/cadet/gnunet-service-cadet_dht.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_dht.c | 373 |
1 files changed, 150 insertions, 223 deletions
diff --git a/src/cadet/gnunet-service-cadet_dht.c b/src/cadet/gnunet-service-cadet_dht.c index 22673b167..f00c0caf3 100644 --- a/src/cadet/gnunet-service-cadet_dht.c +++ b/src/cadet/gnunet-service-cadet_dht.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2013 GNUnet e.V. | 3 | Copyright (C) 2013, 2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -17,25 +17,41 @@ | |||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | Boston, MA 02110-1301, USA. | 18 | Boston, MA 02110-1301, USA. |
19 | */ | 19 | */ |
20 | 20 | /** | |
21 | * @file cadet/gnunet-service-cadet_dht.c | ||
22 | * @brief Information we track per peer. | ||
23 | * @author Bartlomiej Polot | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
21 | 26 | ||
22 | #include "platform.h" | 27 | #include "platform.h" |
23 | #include "gnunet_util_lib.h" | 28 | #include "gnunet_util_lib.h" |
24 | |||
25 | #include "gnunet_dht_service.h" | 29 | #include "gnunet_dht_service.h" |
26 | #include "gnunet_statistics_service.h" | 30 | #include "gnunet_statistics_service.h" |
27 | 31 | #include "gnunet-service-cadet.h" | |
28 | #include "cadet_path.h" | ||
29 | #include "gnunet-service-cadet_dht.h" | 32 | #include "gnunet-service-cadet_dht.h" |
30 | #include "gnunet-service-cadet_peer.h" | ||
31 | #include "gnunet-service-cadet_hello.h" | 33 | #include "gnunet-service-cadet_hello.h" |
34 | #include "gnunet-service-cadet_peer.h" | ||
35 | #include "gnunet-service-cadet_paths.h" | ||
32 | 36 | ||
33 | #define LOG(level, ...) GNUNET_log_from (level,"cadet-dht",__VA_ARGS__) | 37 | /** |
38 | * How long do we wait before first announcing our presence to the DHT. | ||
39 | * Used to wait for our HELLO to be available. Note that we also get | ||
40 | * notifications when our HELLO is ready, so this is just the maximum | ||
41 | * we wait for the first notification. | ||
42 | */ | ||
43 | #define STARTUP_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 500) | ||
34 | 44 | ||
45 | /** | ||
46 | * How long do we wait after we get an updated HELLO before publishing? | ||
47 | * Allows for the HELLO to be updated again quickly, for example in | ||
48 | * case multiple addresses changed and we got a partial update. | ||
49 | */ | ||
50 | #define CHANGE_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100) | ||
51 | |||
52 | |||
53 | #define LOG(level, ...) GNUNET_log_from (level,"cadet-dht",__VA_ARGS__) | ||
35 | 54 | ||
36 | /******************************************************************************/ | ||
37 | /******************************** STRUCTS **********************************/ | ||
38 | /******************************************************************************/ | ||
39 | 55 | ||
40 | /** | 56 | /** |
41 | * Handle for DHT searches. | 57 | * Handle for DHT searches. |
@@ -47,42 +63,9 @@ struct GCD_search_handle | |||
47 | */ | 63 | */ |
48 | struct GNUNET_DHT_GetHandle *dhtget; | 64 | struct GNUNET_DHT_GetHandle *dhtget; |
49 | 65 | ||
50 | /** | ||
51 | * Provided callback to call when a path is found. | ||
52 | */ | ||
53 | GCD_search_callback callback; | ||
54 | |||
55 | /** | ||
56 | * Provided closure. | ||
57 | */ | ||
58 | void *cls; | ||
59 | |||
60 | /** | ||
61 | * Peer ID searched for | ||
62 | */ | ||
63 | GNUNET_PEER_Id peer_id; | ||
64 | }; | 66 | }; |
65 | 67 | ||
66 | 68 | ||
67 | /******************************************************************************/ | ||
68 | /******************************* GLOBALS ***********************************/ | ||
69 | /******************************************************************************/ | ||
70 | |||
71 | /** | ||
72 | * Global handle to the statistics service. | ||
73 | */ | ||
74 | extern struct GNUNET_STATISTICS_Handle *stats; | ||
75 | |||
76 | /** | ||
77 | * Own ID (short value). | ||
78 | */ | ||
79 | extern GNUNET_PEER_Id myid; | ||
80 | |||
81 | /** | ||
82 | * Own ID (full value). | ||
83 | */ | ||
84 | extern struct GNUNET_PeerIdentity my_full_id; | ||
85 | |||
86 | /** | 69 | /** |
87 | * Handle to use DHT. | 70 | * Handle to use DHT. |
88 | */ | 71 | */ |
@@ -94,69 +77,20 @@ static struct GNUNET_DHT_Handle *dht_handle; | |||
94 | static struct GNUNET_TIME_Relative id_announce_time; | 77 | static struct GNUNET_TIME_Relative id_announce_time; |
95 | 78 | ||
96 | /** | 79 | /** |
97 | * DHT replication level, see DHT API: GNUNET_DHT_get_start, GNUNET_DHT_put. | 80 | * DHT replication level, see DHT API: #GNUNET_DHT_get_start(), #GNUNET_DHT_put(). |
98 | */ | 81 | */ |
99 | static unsigned long long dht_replication_level; | 82 | static unsigned long long dht_replication_level; |
100 | 83 | ||
101 | /** | 84 | /** |
102 | * Task to periodically announce itself in the network. | 85 | * Task to periodically announce itself in the network. |
103 | */ | 86 | */ |
104 | static struct GNUNET_SCHEDULER_Task * announce_id_task; | 87 | static struct GNUNET_SCHEDULER_Task *announce_id_task; |
105 | 88 | ||
106 | /** | 89 | /** |
107 | * Delay for the next ID announce. | 90 | * Delay for the next ID announce. |
108 | */ | 91 | */ |
109 | static struct GNUNET_TIME_Relative announce_delay; | 92 | static struct GNUNET_TIME_Relative announce_delay; |
110 | 93 | ||
111 | /** | ||
112 | * GET requests to stop on shutdown. | ||
113 | */ | ||
114 | static struct GNUNET_CONTAINER_MultiHashMap32 *get_requests; | ||
115 | |||
116 | /******************************************************************************/ | ||
117 | /******************************** STATIC ***********************************/ | ||
118 | /******************************************************************************/ | ||
119 | |||
120 | |||
121 | /** | ||
122 | * Build a PeerPath from the paths returned from the DHT, reversing the paths | ||
123 | * to obtain a local peer -> destination path and interning the peer ids. | ||
124 | * | ||
125 | * @return Newly allocated and created path | ||
126 | * | ||
127 | * FIXME refactor and use build_path_from_peer_ids | ||
128 | */ | ||
129 | static struct CadetPeerPath * | ||
130 | path_build_from_dht (const struct GNUNET_PeerIdentity *get_path, | ||
131 | unsigned int get_path_length, | ||
132 | const struct GNUNET_PeerIdentity *put_path, | ||
133 | unsigned int put_path_length) | ||
134 | { | ||
135 | size_t size = get_path_length + put_path_length + 1; | ||
136 | struct GNUNET_PeerIdentity peers[size]; | ||
137 | const struct GNUNET_PeerIdentity *peer; | ||
138 | struct CadetPeerPath *p; | ||
139 | unsigned int own_pos; | ||
140 | int i; | ||
141 | |||
142 | peers[0] = my_full_id; | ||
143 | LOG (GNUNET_ERROR_TYPE_DEBUG, " GET has %d hops.\n", get_path_length); | ||
144 | for (i = 0 ; i < get_path_length; i++) | ||
145 | { | ||
146 | peer = &get_path[get_path_length - i - 1]; | ||
147 | LOG (GNUNET_ERROR_TYPE_DEBUG, " From GET: %s\n", GNUNET_i2s (peer)); | ||
148 | peers[i + 1] = *peer; | ||
149 | } | ||
150 | for (i = 0 ; i < put_path_length; i++) | ||
151 | { | ||
152 | peer = &put_path[put_path_length - i - 1]; | ||
153 | LOG (GNUNET_ERROR_TYPE_DEBUG, " From PUT: %s\n", GNUNET_i2s (peer)); | ||
154 | peers[i + get_path_length + 1] = *peer; | ||
155 | } | ||
156 | p = path_build_from_peer_ids (peers, size, myid, &own_pos); | ||
157 | return p; | ||
158 | } | ||
159 | |||
160 | 94 | ||
161 | /** | 95 | /** |
162 | * Function to process paths received for a new peer addition. The recorded | 96 | * Function to process paths received for a new peer addition. The recorded |
@@ -176,42 +110,34 @@ path_build_from_dht (const struct GNUNET_PeerIdentity *get_path, | |||
176 | */ | 110 | */ |
177 | static void | 111 | static void |
178 | dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, | 112 | dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, |
179 | const struct GNUNET_HashCode * key, | 113 | const struct GNUNET_HashCode *key, |
180 | const struct GNUNET_PeerIdentity *get_path, | 114 | const struct GNUNET_PeerIdentity *get_path, |
181 | unsigned int get_path_length, | 115 | unsigned int get_path_length, |
182 | const struct GNUNET_PeerIdentity *put_path, | 116 | const struct GNUNET_PeerIdentity *put_path, |
183 | unsigned int put_path_length, enum GNUNET_BLOCK_Type type, | 117 | unsigned int put_path_length, |
184 | size_t size, const void *data) | 118 | enum GNUNET_BLOCK_Type type, |
119 | size_t size, | ||
120 | const void *data) | ||
185 | { | 121 | { |
186 | struct GCD_search_handle *h = cls; | 122 | const struct GNUNET_HELLO_Message *hello = data; |
187 | struct GNUNET_HELLO_Message *hello; | ||
188 | struct CadetPeerPath *p; | ||
189 | struct CadetPeer *peer; | 123 | struct CadetPeer *peer; |
190 | char *s; | ||
191 | 124 | ||
192 | p = path_build_from_dht (get_path, get_path_length, | 125 | GCPP_try_path_from_dht (get_path, |
193 | put_path, put_path_length); | 126 | get_path_length, |
194 | if (NULL == p) | 127 | put_path, |
128 | put_path_length); | ||
129 | if ( (size >= sizeof (struct GNUNET_HELLO_Message)) && | ||
130 | (ntohs (hello->header.size) == size) && | ||
131 | (size == GNUNET_HELLO_size (hello)) ) | ||
195 | { | 132 | { |
196 | GNUNET_break_op (0); | 133 | peer = GCP_get (&put_path[0], |
197 | return; | 134 | GNUNET_YES); |
135 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
136 | "Got HELLO for %s\n", | ||
137 | GCP_2s (peer)); | ||
138 | GCP_set_hello (peer, | ||
139 | hello); | ||
198 | } | 140 | } |
199 | |||
200 | s = path_2s (p); | ||
201 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
202 | "Got path from DHT: %s\n", | ||
203 | s); | ||
204 | GNUNET_free_non_null (s); | ||
205 | |||
206 | peer = GCP_get_short (p->peers[p->length - 1], GNUNET_YES); | ||
207 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
208 | "Got HELLO for %s\n", | ||
209 | GCP_2s (peer)); | ||
210 | h->callback (h->cls, p); | ||
211 | path_destroy (p); | ||
212 | hello = (struct GNUNET_HELLO_Message *) data; | ||
213 | GCP_set_hello (peer, hello); | ||
214 | GCP_try_connect (peer); | ||
215 | } | 141 | } |
216 | 142 | ||
217 | 143 | ||
@@ -229,19 +155,10 @@ announce_id (void *cls) | |||
229 | struct GNUNET_TIME_Absolute expiration; | 155 | struct GNUNET_TIME_Absolute expiration; |
230 | struct GNUNET_TIME_Relative next_put; | 156 | struct GNUNET_TIME_Relative next_put; |
231 | 157 | ||
232 | announce_id_task = NULL; | ||
233 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Announce ID\n"); | ||
234 | hello = GCH_get_mine (); | 158 | hello = GCH_get_mine (); |
235 | size = (NULL != hello) ? GNUNET_HELLO_size (hello) : 0; | 159 | size = (NULL != hello) ? GNUNET_HELLO_size (hello) : 0; |
236 | if ( (NULL == hello) || (0 == size) ) | 160 | if (0 == size) |
237 | { | 161 | { |
238 | /* Peerinfo gave us no hello yet, try again soon. */ | ||
239 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
240 | " no hello, waiting!\n"); | ||
241 | GNUNET_STATISTICS_update (stats, | ||
242 | "# DHT announce skipped (no hello)", | ||
243 | 1, | ||
244 | GNUNET_NO); | ||
245 | expiration = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), | 162 | expiration = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), |
246 | announce_delay); | 163 | announce_delay); |
247 | announce_delay = GNUNET_TIME_STD_BACKOFF (announce_delay); | 164 | announce_delay = GNUNET_TIME_STD_BACKOFF (announce_delay); |
@@ -252,71 +169,64 @@ announce_id (void *cls) | |||
252 | announce_delay = GNUNET_TIME_UNIT_SECONDS; | 169 | announce_delay = GNUNET_TIME_UNIT_SECONDS; |
253 | } | 170 | } |
254 | 171 | ||
255 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
256 | "Hello %p size: %u\n", | ||
257 | hello, | ||
258 | size); | ||
259 | if (NULL != hello) | ||
260 | { | ||
261 | GNUNET_STATISTICS_update (stats, | ||
262 | "# DHT announce", | ||
263 | 1, GNUNET_NO); | ||
264 | memset (&phash, | ||
265 | 0, | ||
266 | sizeof (phash)); | ||
267 | GNUNET_memcpy (&phash, | ||
268 | &my_full_id, | ||
269 | sizeof (my_full_id)); | ||
270 | GNUNET_DHT_put (dht_handle, /* DHT handle */ | ||
271 | &phash, /* Key to use */ | ||
272 | dht_replication_level, /* Replication level */ | ||
273 | GNUNET_DHT_RO_RECORD_ROUTE | ||
274 | | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, /* DHT options */ | ||
275 | GNUNET_BLOCK_TYPE_DHT_HELLO, /* Block type */ | ||
276 | size, /* Size of the data */ | ||
277 | (const char *) hello, /* Data itself */ | ||
278 | expiration, /* Data expiration */ | ||
279 | NULL, /* Continuation */ | ||
280 | NULL); /* Continuation closure */ | ||
281 | } | ||
282 | /* Call again in id_announce_time, unless HELLO expires first, | 172 | /* Call again in id_announce_time, unless HELLO expires first, |
283 | * but wait at least 1s. */ | 173 | * but wait at least 1s. */ |
284 | next_put = GNUNET_TIME_absolute_get_remaining (expiration); | 174 | next_put |
285 | next_put = GNUNET_TIME_relative_min (next_put, | 175 | = GNUNET_TIME_absolute_get_remaining (expiration); |
286 | id_announce_time); | 176 | next_put |
287 | next_put = GNUNET_TIME_relative_max (next_put, | 177 | = GNUNET_TIME_relative_min (next_put, |
288 | GNUNET_TIME_UNIT_SECONDS); | 178 | id_announce_time); |
289 | announce_id_task = GNUNET_SCHEDULER_add_delayed (next_put, | 179 | next_put |
290 | &announce_id, | 180 | = GNUNET_TIME_relative_max (next_put, |
291 | cls); | 181 | GNUNET_TIME_UNIT_SECONDS); |
182 | announce_id_task | ||
183 | = GNUNET_SCHEDULER_add_delayed (next_put, | ||
184 | &announce_id, | ||
185 | cls); | ||
186 | GNUNET_STATISTICS_update (stats, | ||
187 | "# DHT announce", | ||
188 | 1, | ||
189 | GNUNET_NO); | ||
190 | memset (&phash, | ||
191 | 0, | ||
192 | sizeof (phash)); | ||
193 | GNUNET_memcpy (&phash, | ||
194 | &my_full_id, | ||
195 | sizeof (my_full_id)); | ||
196 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
197 | "Announcing my HELLO (%u bytes) in the DHT\n", | ||
198 | size); | ||
199 | GNUNET_DHT_put (dht_handle, /* DHT handle */ | ||
200 | &phash, /* Key to use */ | ||
201 | dht_replication_level, /* Replication level */ | ||
202 | GNUNET_DHT_RO_RECORD_ROUTE | ||
203 | | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, /* DHT options */ | ||
204 | GNUNET_BLOCK_TYPE_DHT_HELLO, /* Block type */ | ||
205 | size, /* Size of the data */ | ||
206 | (const char *) hello, /* Data itself */ | ||
207 | expiration, /* Data expiration */ | ||
208 | NULL, /* Continuation */ | ||
209 | NULL); /* Continuation closure */ | ||
292 | } | 210 | } |
293 | 211 | ||
212 | |||
294 | /** | 213 | /** |
295 | * Iterator over hash map entries and stop GET requests before disconnecting | 214 | * Function called by the HELLO subsystem whenever OUR hello |
296 | * from the DHT. | 215 | * changes. Re-triggers the DHT PUT immediately. |
297 | * | ||
298 | * @param cls Closure (unused) | ||
299 | * @param key Current peer ID. | ||
300 | * @param value Value in the hash map (GCD_search_handle). | ||
301 | * | ||
302 | * @return #GNUNET_YES, we should continue to iterate, | ||
303 | */ | 216 | */ |
304 | int | 217 | void |
305 | stop_get (void *cls, | 218 | GCD_hello_update () |
306 | uint32_t key, | ||
307 | void *value) | ||
308 | { | 219 | { |
309 | struct GCD_search_handle *h = value; | 220 | if (NULL == announce_id_task) |
310 | 221 | return; /* too early */ | |
311 | GCD_search_stop (h); | 222 | GNUNET_SCHEDULER_cancel (announce_id_task); |
312 | return GNUNET_YES; | 223 | announce_id_task |
224 | = GNUNET_SCHEDULER_add_delayed (CHANGE_DELAY, | ||
225 | &announce_id, | ||
226 | NULL); | ||
313 | } | 227 | } |
314 | 228 | ||
315 | 229 | ||
316 | /******************************************************************************/ | ||
317 | /******************************** API ***********************************/ | ||
318 | /******************************************************************************/ | ||
319 | |||
320 | /** | 230 | /** |
321 | * Initialize the DHT subsystem. | 231 | * Initialize the DHT subsystem. |
322 | * | 232 | * |
@@ -325,36 +235,40 @@ stop_get (void *cls, | |||
325 | void | 235 | void |
326 | GCD_init (const struct GNUNET_CONFIGURATION_Handle *c) | 236 | GCD_init (const struct GNUNET_CONFIGURATION_Handle *c) |
327 | { | 237 | { |
328 | LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n"); | ||
329 | if (GNUNET_OK != | 238 | if (GNUNET_OK != |
330 | GNUNET_CONFIGURATION_get_value_number (c, "CADET", | 239 | GNUNET_CONFIGURATION_get_value_number (c, |
240 | "CADET", | ||
331 | "DHT_REPLICATION_LEVEL", | 241 | "DHT_REPLICATION_LEVEL", |
332 | &dht_replication_level)) | 242 | &dht_replication_level)) |
333 | { | 243 | { |
334 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, "CADET", | 244 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, |
335 | "DHT_REPLICATION_LEVEL", "USING DEFAULT"); | 245 | "CADET", |
246 | "DHT_REPLICATION_LEVEL", | ||
247 | "USING DEFAULT"); | ||
336 | dht_replication_level = 3; | 248 | dht_replication_level = 3; |
337 | } | 249 | } |
338 | 250 | ||
339 | if (GNUNET_OK != | 251 | if (GNUNET_OK != |
340 | GNUNET_CONFIGURATION_get_value_time (c, "CADET", "ID_ANNOUNCE_TIME", | 252 | GNUNET_CONFIGURATION_get_value_time (c, |
253 | "CADET", | ||
254 | "ID_ANNOUNCE_TIME", | ||
341 | &id_announce_time)) | 255 | &id_announce_time)) |
342 | { | 256 | { |
343 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "CADET", | 257 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, |
344 | "ID_ANNOUNCE_TIME", "MISSING"); | 258 | "CADET", |
259 | "ID_ANNOUNCE_TIME", | ||
260 | "MISSING"); | ||
345 | GNUNET_SCHEDULER_shutdown (); | 261 | GNUNET_SCHEDULER_shutdown (); |
346 | return; | 262 | return; |
347 | } | 263 | } |
348 | 264 | ||
349 | dht_handle = GNUNET_DHT_connect (c, 64); | 265 | dht_handle = GNUNET_DHT_connect (c, |
350 | if (NULL == dht_handle) | 266 | 64); |
351 | { | 267 | GNUNET_break (NULL != dht_handle); |
352 | GNUNET_break (0); | ||
353 | } | ||
354 | |||
355 | announce_delay = GNUNET_TIME_UNIT_SECONDS; | 268 | announce_delay = GNUNET_TIME_UNIT_SECONDS; |
356 | announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, NULL); | 269 | announce_id_task = GNUNET_SCHEDULER_add_delayed (STARTUP_DELAY, |
357 | get_requests = GNUNET_CONTAINER_multihashmap32_create (32); | 270 | &announce_id, |
271 | NULL); | ||
358 | } | 272 | } |
359 | 273 | ||
360 | 274 | ||
@@ -364,10 +278,7 @@ GCD_init (const struct GNUNET_CONFIGURATION_Handle *c) | |||
364 | void | 278 | void |
365 | GCD_shutdown (void) | 279 | GCD_shutdown (void) |
366 | { | 280 | { |
367 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down DHT\n"); | 281 | if (NULL != dht_handle) |
368 | GNUNET_CONTAINER_multihashmap32_iterate (get_requests, &stop_get, NULL); | ||
369 | GNUNET_CONTAINER_multihashmap32_destroy (get_requests); | ||
370 | if (dht_handle != NULL) | ||
371 | { | 282 | { |
372 | GNUNET_DHT_disconnect (dht_handle); | 283 | GNUNET_DHT_disconnect (dht_handle); |
373 | dht_handle = NULL; | 284 | dht_handle = NULL; |
@@ -379,22 +290,31 @@ GCD_shutdown (void) | |||
379 | } | 290 | } |
380 | } | 291 | } |
381 | 292 | ||
293 | |||
294 | /** | ||
295 | * Search DHT for paths to @a peeR_id | ||
296 | * | ||
297 | * @param peer_id peer to search for | ||
298 | * @return handle to abort search | ||
299 | */ | ||
382 | struct GCD_search_handle * | 300 | struct GCD_search_handle * |
383 | GCD_search (const struct GNUNET_PeerIdentity *peer_id, | 301 | GCD_search (const struct GNUNET_PeerIdentity *peer_id) |
384 | GCD_search_callback callback, void *cls) | ||
385 | { | 302 | { |
386 | struct GNUNET_HashCode phash; | 303 | struct GNUNET_HashCode phash; |
387 | struct GCD_search_handle *h; | 304 | struct GCD_search_handle *h; |
388 | 305 | ||
389 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting DHT GET for peer %s\n", | 306 | GNUNET_STATISTICS_update (stats, |
390 | GNUNET_i2s (peer_id)); | 307 | "# DHT search", |
391 | GNUNET_STATISTICS_update (stats, "# DHT search", 1, GNUNET_NO); | 308 | 1, |
392 | memset (&phash, 0, sizeof (phash)); | 309 | GNUNET_NO); |
393 | GNUNET_memcpy (&phash, peer_id, sizeof (*peer_id)); | 310 | memset (&phash, |
311 | 0, | ||
312 | sizeof (phash)); | ||
313 | GNUNET_memcpy (&phash, | ||
314 | peer_id, | ||
315 | sizeof (*peer_id)); | ||
316 | |||
394 | h = GNUNET_new (struct GCD_search_handle); | 317 | h = GNUNET_new (struct GCD_search_handle); |
395 | h->peer_id = GNUNET_PEER_intern (peer_id); | ||
396 | h->callback = callback; | ||
397 | h->cls = cls; | ||
398 | h->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */ | 318 | h->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */ |
399 | GNUNET_BLOCK_TYPE_DHT_HELLO, /* type */ | 319 | GNUNET_BLOCK_TYPE_DHT_HELLO, /* type */ |
400 | &phash, /* key to search */ | 320 | &phash, /* key to search */ |
@@ -405,20 +325,27 @@ GCD_search (const struct GNUNET_PeerIdentity *peer_id, | |||
405 | 0, /* xquery bits */ | 325 | 0, /* xquery bits */ |
406 | &dht_get_id_handler, | 326 | &dht_get_id_handler, |
407 | h); | 327 | h); |
408 | GNUNET_CONTAINER_multihashmap32_put (get_requests, | 328 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
409 | h->peer_id, | 329 | "Starting DHT GET for peer %s (%p)\n", |
410 | h, | 330 | GNUNET_i2s (peer_id), |
411 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 331 | h); |
412 | return h; | 332 | return h; |
413 | } | 333 | } |
414 | 334 | ||
415 | 335 | ||
336 | /** | ||
337 | * Stop DHT search started with #GCD_search(). | ||
338 | * | ||
339 | * @param h handle to search to stop | ||
340 | */ | ||
416 | void | 341 | void |
417 | GCD_search_stop (struct GCD_search_handle *h) | 342 | GCD_search_stop (struct GCD_search_handle *h) |
418 | { | 343 | { |
419 | GNUNET_break (GNUNET_OK == | 344 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
420 | GNUNET_CONTAINER_multihashmap32_remove (get_requests, | 345 | "Stopping DHT GET %p\n", |
421 | h->peer_id, h)); | 346 | h); |
422 | GNUNET_DHT_get_stop (h->dhtget); | 347 | GNUNET_DHT_get_stop (h->dhtget); |
423 | GNUNET_free (h); | 348 | GNUNET_free (h); |
424 | } | 349 | } |
350 | |||
351 | /* end of gnunet-service-cadet_dht.c */ | ||