diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-06-13 14:37:12 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-06-13 14:37:12 +0000 |
commit | 832d12049add37805697104b9f8eaae420eef406 (patch) | |
tree | 6f0214a2f7d6fff7761c1f2f3a0b0d4fcd2f2f26 /src/peerinfo | |
parent | d2b611a870d2b6de2fe83b95a2497e062693d4d8 (diff) | |
download | gnunet-832d12049add37805697104b9f8eaae420eef406.tar.gz gnunet-832d12049add37805697104b9f8eaae420eef406.zip |
-do not store/keep HELLOs with expired addresses on disk (#1932)
Diffstat (limited to 'src/peerinfo')
-rw-r--r-- | src/peerinfo/gnunet-service-peerinfo.c | 186 |
1 files changed, 138 insertions, 48 deletions
diff --git a/src/peerinfo/gnunet-service-peerinfo.c b/src/peerinfo/gnunet-service-peerinfo.c index 59f9a9b6e..9c3ab4032 100644 --- a/src/peerinfo/gnunet-service-peerinfo.c +++ b/src/peerinfo/gnunet-service-peerinfo.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2001, 2002, 2004, 2005, 2007, 2009, 2010 Christian Grothoff (and other contributing authors) | 3 | (C) 2001, 2002, 2004, 2005, 2007, 2009, 2010, 2012 Christian Grothoff (and other contributing authors) |
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 |
@@ -28,7 +28,7 @@ | |||
28 | * @author Christian Grothoff | 28 | * @author Christian Grothoff |
29 | * | 29 | * |
30 | * TODO: | 30 | * TODO: |
31 | * - HostEntries are never 'free'd (add expiration, upper bound?) | 31 | * - notify clients when addresses in HELLO expire (#1933) |
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include "platform.h" | 34 | #include "platform.h" |
@@ -103,7 +103,7 @@ make_info_message (const struct HostEntry *he) | |||
103 | struct InfoMessage *im; | 103 | struct InfoMessage *im; |
104 | size_t hs; | 104 | size_t hs; |
105 | 105 | ||
106 | hs = (he->hello == NULL) ? 0 : GNUNET_HELLO_size (he->hello); | 106 | hs = (NULL == he->hello) ? 0 : GNUNET_HELLO_size (he->hello); |
107 | im = GNUNET_malloc (sizeof (struct InfoMessage) + hs); | 107 | im = GNUNET_malloc (sizeof (struct InfoMessage) + hs); |
108 | im->header.size = htons (hs + sizeof (struct InfoMessage)); | 108 | im->header.size = htons (hs + sizeof (struct InfoMessage)); |
109 | im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO); | 109 | im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO); |
@@ -140,6 +140,25 @@ discard_expired (void *cls, const struct GNUNET_HELLO_Address *address, | |||
140 | 140 | ||
141 | 141 | ||
142 | /** | 142 | /** |
143 | * Address iterator that counts the remaining addresses. | ||
144 | * | ||
145 | * @param cls pointer to the counter | ||
146 | * @param address the address | ||
147 | * @param expiration expiration time for the address | ||
148 | * @return GNUNET_OK (always) | ||
149 | */ | ||
150 | static int | ||
151 | count_addresses (void *cls, const struct GNUNET_HELLO_Address *address, | ||
152 | struct GNUNET_TIME_Absolute expiration) | ||
153 | { | ||
154 | unsigned int *cnt = cls; | ||
155 | |||
156 | (*cnt)++; | ||
157 | return GNUNET_OK; | ||
158 | } | ||
159 | |||
160 | |||
161 | /** | ||
143 | * Get the filename under which we would store the GNUNET_HELLO_Message | 162 | * Get the filename under which we would store the GNUNET_HELLO_Message |
144 | * for the given host and protocol. | 163 | * for the given host and protocol. |
145 | * | 164 | * |
@@ -177,19 +196,25 @@ notify_all (struct HostEntry *entry) | |||
177 | 196 | ||
178 | 197 | ||
179 | /** | 198 | /** |
180 | * Try to read the HELLO in the given filename and discard expired addresses. | 199 | * Try to read the HELLO in the given filename and discard expired |
200 | * addresses. Removes the file if the HELLO is mal-formed. If all | ||
201 | * addresses are expired, the HELLO is also removed (but the HELLO | ||
202 | * with the public key is still returned if it was found and valid). | ||
181 | * | 203 | * |
182 | * @param fn name of the file | 204 | * @param fn name of the file |
205 | * @param unlink_garbage if GNUNET_YES, try to remove useless files | ||
183 | * @return HELLO of the file, NULL on error | 206 | * @return HELLO of the file, NULL on error |
184 | */ | 207 | */ |
185 | static struct GNUNET_HELLO_Message * | 208 | static struct GNUNET_HELLO_Message * |
186 | read_host_file (const char *fn) | 209 | read_host_file (const char *fn, |
210 | int unlink_garbage) | ||
187 | { | 211 | { |
188 | char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; | 212 | char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; |
189 | const struct GNUNET_HELLO_Message *hello; | 213 | const struct GNUNET_HELLO_Message *hello; |
190 | struct GNUNET_HELLO_Message *hello_clean; | 214 | struct GNUNET_HELLO_Message *hello_clean; |
191 | int size; | 215 | int size; |
192 | struct GNUNET_TIME_Absolute now; | 216 | struct GNUNET_TIME_Absolute now; |
217 | unsigned int left; | ||
193 | 218 | ||
194 | if (GNUNET_YES != GNUNET_DISK_file_test (fn)) | 219 | if (GNUNET_YES != GNUNET_DISK_file_test (fn)) |
195 | return NULL; | 220 | return NULL; |
@@ -202,12 +227,25 @@ read_host_file (const char *fn) | |||
202 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 227 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
203 | _("Failed to parse HELLO in file `%s'\n"), | 228 | _("Failed to parse HELLO in file `%s'\n"), |
204 | fn); | 229 | fn); |
230 | if ( (GNUNET_YES == unlink_garbage) && | ||
231 | (0 != UNLINK (fn)) ) | ||
232 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); | ||
205 | return NULL; | 233 | return NULL; |
206 | } | 234 | } |
207 | now = GNUNET_TIME_absolute_get (); | 235 | now = GNUNET_TIME_absolute_get (); |
208 | hello_clean = | 236 | hello_clean = |
209 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES, &discard_expired, | 237 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES, &discard_expired, |
210 | &now); | 238 | &now); |
239 | left = 0; | ||
240 | (void) GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &count_addresses, | ||
241 | &left); | ||
242 | if (0 == left) | ||
243 | { | ||
244 | /* no addresses left, remove from disk */ | ||
245 | if ( (GNUNET_YES == unlink_garbage) && | ||
246 | (0 != UNLINK (fn)) ) | ||
247 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); | ||
248 | } | ||
211 | return hello_clean; | 249 | return hello_clean; |
212 | } | 250 | } |
213 | 251 | ||
@@ -224,7 +262,7 @@ add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity) | |||
224 | char *fn; | 262 | char *fn; |
225 | 263 | ||
226 | entry = GNUNET_CONTAINER_multihashmap_get (hostmap, &identity->hashPubKey); | 264 | entry = GNUNET_CONTAINER_multihashmap_get (hostmap, &identity->hashPubKey); |
227 | if (entry != NULL) | 265 | if (NULL != entry) |
228 | return; | 266 | return; |
229 | GNUNET_STATISTICS_update (stats, gettext_noop ("# peers known"), 1, | 267 | GNUNET_STATISTICS_update (stats, gettext_noop ("# peers known"), 1, |
230 | GNUNET_NO); | 268 | GNUNET_NO); |
@@ -233,7 +271,7 @@ add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity) | |||
233 | GNUNET_CONTAINER_multihashmap_put (hostmap, &identity->hashPubKey, entry, | 271 | GNUNET_CONTAINER_multihashmap_put (hostmap, &identity->hashPubKey, entry, |
234 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 272 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); |
235 | fn = get_host_filename (identity); | 273 | fn = get_host_filename (identity); |
236 | entry->hello = read_host_file (fn); | 274 | entry->hello = read_host_file (fn, GNUNET_YES); |
237 | GNUNET_free (fn); | 275 | GNUNET_free (fn); |
238 | notify_all (entry); | 276 | notify_all (entry); |
239 | } | 277 | } |
@@ -260,6 +298,26 @@ remove_garbage (const char *fullname) | |||
260 | 298 | ||
261 | 299 | ||
262 | /** | 300 | /** |
301 | * Closure for 'hosts_directory_scan_callback'. | ||
302 | */ | ||
303 | struct DirScanContext | ||
304 | { | ||
305 | /** | ||
306 | * GNUNET_YES if we should remove files that are broken, | ||
307 | * GNUNET_NO if the directory we are iterating over should | ||
308 | * be treated as read-only by us. | ||
309 | */ | ||
310 | int remove_files; | ||
311 | |||
312 | /** | ||
313 | * Counter for the number of (valid) entries found, incremented | ||
314 | * by one for each match. | ||
315 | */ | ||
316 | unsigned int matched; | ||
317 | }; | ||
318 | |||
319 | |||
320 | /** | ||
263 | * Function that is called on each HELLO file in a particular directory. | 321 | * Function that is called on each HELLO file in a particular directory. |
264 | * Try to parse the file and add the HELLO to our list. | 322 | * Try to parse the file and add the HELLO to our list. |
265 | * | 323 | * |
@@ -271,53 +329,55 @@ remove_garbage (const char *fullname) | |||
271 | static int | 329 | static int |
272 | hosts_directory_scan_callback (void *cls, const char *fullname) | 330 | hosts_directory_scan_callback (void *cls, const char *fullname) |
273 | { | 331 | { |
274 | unsigned int *matched = cls; | 332 | struct DirScanContext *dsc = cls; |
275 | struct GNUNET_PeerIdentity identity; | 333 | struct GNUNET_PeerIdentity identity; |
276 | const char *filename; | 334 | const char *filename; |
277 | struct HostEntry *entry; | 335 | struct HostEntry *entry; |
278 | struct GNUNET_HELLO_Message *hello; | 336 | struct GNUNET_HELLO_Message *hello; |
337 | struct GNUNET_PeerIdentity id; | ||
279 | 338 | ||
280 | if (GNUNET_DISK_file_test (fullname) != GNUNET_YES) | 339 | if (GNUNET_YES != GNUNET_DISK_file_test (fullname)) |
281 | return GNUNET_OK; /* ignore non-files */ | 340 | return GNUNET_OK; /* ignore non-files */ |
282 | if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) | 341 | if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) |
283 | { | 342 | { |
284 | if (NULL != matched) | 343 | if (GNUNET_YES == dsc->remove_files) |
285 | remove_garbage (fullname); | 344 | remove_garbage (fullname); |
286 | return GNUNET_OK; | 345 | return GNUNET_OK; |
287 | } | 346 | } |
288 | filename = | 347 | filename = |
289 | &fullname[strlen (fullname) - | 348 | &fullname[strlen (fullname) - |
290 | sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1]; | 349 | sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1]; |
291 | if (filename[-1] != DIR_SEPARATOR) | 350 | if (DIR_SEPARATOR != filename[-1]) |
292 | { | 351 | { |
293 | if (NULL != matched) | 352 | if (GNUNET_YES == dsc->remove_files) |
294 | remove_garbage (fullname); | 353 | remove_garbage (fullname); |
295 | return GNUNET_OK; | 354 | return GNUNET_OK; |
296 | } | 355 | } |
297 | if (GNUNET_OK != | 356 | if (GNUNET_OK != |
298 | GNUNET_CRYPTO_hash_from_string (filename, &identity.hashPubKey)) | 357 | GNUNET_CRYPTO_hash_from_string (filename, &identity.hashPubKey)) |
299 | { | 358 | { |
300 | if (NULL != (hello = read_host_file (filename))) | 359 | /* odd filename, but might still be valid, try getting identity from HELLO */ |
360 | if ( (NULL != (hello = read_host_file (filename, | ||
361 | dsc->remove_files))) && | ||
362 | (GNUNET_OK == | ||
363 | GNUNET_HELLO_get_id (hello, | ||
364 | &id)) ) | ||
301 | { | 365 | { |
366 | /* ok, found something valid, remember HELLO */ | ||
302 | entry = GNUNET_malloc (sizeof (struct HostEntry)); | 367 | entry = GNUNET_malloc (sizeof (struct HostEntry)); |
303 | if (GNUNET_OK == | 368 | entry->identity = id; |
304 | GNUNET_HELLO_get_id (hello, | 369 | GNUNET_CONTAINER_multihashmap_put (hostmap, &entry->identity.hashPubKey, entry, |
305 | &entry->identity)) | 370 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); |
306 | { | 371 | entry->hello = hello; |
307 | GNUNET_CONTAINER_multihashmap_put (hostmap, &entry->identity.hashPubKey, entry, | 372 | notify_all (entry); |
308 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 373 | dsc->matched++; |
309 | entry->hello = hello; | 374 | return GNUNET_OK; |
310 | notify_all (entry); | ||
311 | return GNUNET_OK; | ||
312 | } | ||
313 | GNUNET_free (entry); | ||
314 | } | 375 | } |
315 | if (NULL != matched) | 376 | if (GNUNET_YES == dsc->remove_files) |
316 | remove_garbage (fullname); | 377 | remove_garbage (fullname); |
317 | return GNUNET_OK; | 378 | return GNUNET_OK; |
318 | } | 379 | } |
319 | if (NULL != matched) | 380 | dsc->matched++; |
320 | (*matched)++; | ||
321 | add_host_to_known_hosts (&identity); | 381 | add_host_to_known_hosts (&identity); |
322 | return GNUNET_OK; | 382 | return GNUNET_OK; |
323 | } | 383 | } |
@@ -334,11 +394,10 @@ cron_scan_directory_data_hosts (void *cls, | |||
334 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 394 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
335 | { | 395 | { |
336 | static unsigned int retries; | 396 | static unsigned int retries; |
337 | unsigned int count; | 397 | struct DirScanContext dsc; |
338 | 398 | ||
339 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 399 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
340 | return; | 400 | return; |
341 | count = 0; | ||
342 | if (GNUNET_SYSERR == GNUNET_DISK_directory_create (networkIdDirectory)) | 401 | if (GNUNET_SYSERR == GNUNET_DISK_directory_create (networkIdDirectory)) |
343 | { | 402 | { |
344 | GNUNET_SCHEDULER_add_delayed_with_priority (DATA_HOST_FREQ, | 403 | GNUNET_SCHEDULER_add_delayed_with_priority (DATA_HOST_FREQ, |
@@ -346,9 +405,11 @@ cron_scan_directory_data_hosts (void *cls, | |||
346 | &cron_scan_directory_data_hosts, NULL); | 405 | &cron_scan_directory_data_hosts, NULL); |
347 | return; | 406 | return; |
348 | } | 407 | } |
408 | dsc.matched = 0; | ||
409 | dsc.remove_files = GNUNET_YES; | ||
349 | GNUNET_DISK_directory_scan (networkIdDirectory, | 410 | GNUNET_DISK_directory_scan (networkIdDirectory, |
350 | &hosts_directory_scan_callback, &count); | 411 | &hosts_directory_scan_callback, &dsc); |
351 | if ((0 == count) && (0 == (++retries & 31))) | 412 | if ((0 == dsc.matched) && (0 == (++retries & 31))) |
352 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, | 413 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, |
353 | _("Still no peers found in `%s'!\n"), networkIdDirectory); | 414 | _("Still no peers found in `%s'!\n"), networkIdDirectory); |
354 | GNUNET_SCHEDULER_add_delayed_with_priority (DATA_HOST_FREQ, | 415 | GNUNET_SCHEDULER_add_delayed_with_priority (DATA_HOST_FREQ, |
@@ -372,11 +433,12 @@ bind_address (const struct GNUNET_PeerIdentity *peer, | |||
372 | struct HostEntry *host; | 433 | struct HostEntry *host; |
373 | struct GNUNET_HELLO_Message *mrg; | 434 | struct GNUNET_HELLO_Message *mrg; |
374 | struct GNUNET_TIME_Absolute delta; | 435 | struct GNUNET_TIME_Absolute delta; |
436 | unsigned int cnt; | ||
375 | 437 | ||
376 | add_host_to_known_hosts (peer); | 438 | add_host_to_known_hosts (peer); |
377 | host = GNUNET_CONTAINER_multihashmap_get (hostmap, &peer->hashPubKey); | 439 | host = GNUNET_CONTAINER_multihashmap_get (hostmap, &peer->hashPubKey); |
378 | GNUNET_assert (host != NULL); | 440 | GNUNET_assert (NULL != host); |
379 | if (host->hello == NULL) | 441 | if (NULL == host->hello) |
380 | { | 442 | { |
381 | host->hello = GNUNET_malloc (GNUNET_HELLO_size (hello)); | 443 | host->hello = GNUNET_malloc (GNUNET_HELLO_size (hello)); |
382 | memcpy (host->hello, hello, GNUNET_HELLO_size (hello)); | 444 | memcpy (host->hello, hello, GNUNET_HELLO_size (hello)); |
@@ -396,14 +458,24 @@ bind_address (const struct GNUNET_PeerIdentity *peer, | |||
396 | fn = get_host_filename (peer); | 458 | fn = get_host_filename (peer); |
397 | if (GNUNET_OK == GNUNET_DISK_directory_create_for_file (fn)) | 459 | if (GNUNET_OK == GNUNET_DISK_directory_create_for_file (fn)) |
398 | { | 460 | { |
399 | if (GNUNET_SYSERR == | 461 | cnt = 0; |
400 | GNUNET_DISK_fn_write (fn, host->hello, GNUNET_HELLO_size (host->hello), | 462 | (void) GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &count_addresses, |
401 | GNUNET_DISK_PERM_USER_READ | | 463 | &cnt); |
402 | GNUNET_DISK_PERM_USER_WRITE | | 464 | if (0 == cnt) |
403 | GNUNET_DISK_PERM_GROUP_READ | | 465 | { |
404 | GNUNET_DISK_PERM_OTHER_READ)) | 466 | /* no valid addresses, don't put HELLO on disk */ |
405 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn); | 467 | (void) UNLINK (fn); |
406 | 468 | } | |
469 | else | ||
470 | { | ||
471 | if (GNUNET_SYSERR == | ||
472 | GNUNET_DISK_fn_write (fn, host->hello, GNUNET_HELLO_size (host->hello), | ||
473 | GNUNET_DISK_PERM_USER_READ | | ||
474 | GNUNET_DISK_PERM_USER_WRITE | | ||
475 | GNUNET_DISK_PERM_GROUP_READ | | ||
476 | GNUNET_DISK_PERM_OTHER_READ)) | ||
477 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn); | ||
478 | } | ||
407 | } | 479 | } |
408 | GNUNET_free (fn); | 480 | GNUNET_free (fn); |
409 | notify_all (host); | 481 | notify_all (host); |
@@ -461,6 +533,7 @@ discard_hosts_helper (void *cls, const char *fn) | |||
461 | const struct GNUNET_HELLO_Message *hello; | 533 | const struct GNUNET_HELLO_Message *hello; |
462 | struct GNUNET_HELLO_Message *new_hello; | 534 | struct GNUNET_HELLO_Message *new_hello; |
463 | int size; | 535 | int size; |
536 | unsigned int cnt; | ||
464 | 537 | ||
465 | size = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer)); | 538 | size = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer)); |
466 | if (size < sizeof (struct GNUNET_MessageHeader)) | 539 | if (size < sizeof (struct GNUNET_MessageHeader)) |
@@ -472,15 +545,17 @@ discard_hosts_helper (void *cls, const char *fn) | |||
472 | } | 545 | } |
473 | hello = (const struct GNUNET_HELLO_Message *) buffer; | 546 | hello = (const struct GNUNET_HELLO_Message *) buffer; |
474 | new_hello = | 547 | new_hello = |
475 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES, &discard_expired, now); | 548 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES, &discard_expired, now); |
476 | if (new_hello != NULL) | 549 | cnt = 0; |
550 | if (NULL != new_hello) | ||
551 | (void) GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &count_addresses, &cnt); | ||
552 | if ( (NULL != new_hello) && (0 < cnt) ) | ||
477 | { | 553 | { |
478 | GNUNET_DISK_fn_write (fn, new_hello, GNUNET_HELLO_size (new_hello), | 554 | GNUNET_DISK_fn_write (fn, new_hello, GNUNET_HELLO_size (new_hello), |
479 | GNUNET_DISK_PERM_USER_READ | | 555 | GNUNET_DISK_PERM_USER_READ | |
480 | GNUNET_DISK_PERM_USER_WRITE | | 556 | GNUNET_DISK_PERM_USER_WRITE | |
481 | GNUNET_DISK_PERM_GROUP_READ | | 557 | GNUNET_DISK_PERM_GROUP_READ | |
482 | GNUNET_DISK_PERM_OTHER_READ); | 558 | GNUNET_DISK_PERM_OTHER_READ); |
483 | GNUNET_free (new_hello); | ||
484 | } | 559 | } |
485 | else | 560 | else |
486 | { | 561 | { |
@@ -488,6 +563,7 @@ discard_hosts_helper (void *cls, const char *fn) | |||
488 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING | | 563 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING | |
489 | GNUNET_ERROR_TYPE_BULK, "unlink", fn); | 564 | GNUNET_ERROR_TYPE_BULK, "unlink", fn); |
490 | } | 565 | } |
566 | GNUNET_free_non_null (new_hello); | ||
491 | return GNUNET_OK; | 567 | return GNUNET_OK; |
492 | } | 568 | } |
493 | 569 | ||
@@ -591,7 +667,13 @@ handle_get_all (void *cls, struct GNUNET_SERVER_Client *client, | |||
591 | 667 | ||
592 | 668 | ||
593 | /** | 669 | /** |
594 | * FIXME. | 670 | * Pass the given client the information we have in the respective |
671 | * host entry; the client is already in the notification context. | ||
672 | * | ||
673 | * @param cls the 'struct GNUNET_SERVER_Client' to notify | ||
674 | * @param key key for the value (unused) | ||
675 | * @param value the 'struct HostEntry' to notify the client about | ||
676 | * @return GNUNET_YES (always, continue to iterate) | ||
595 | */ | 677 | */ |
596 | static int | 678 | static int |
597 | do_notify_entry (void *cls, const struct GNUNET_HashCode * key, void *value) | 679 | do_notify_entry (void *cls, const struct GNUNET_HashCode * key, void *value) |
@@ -628,7 +710,12 @@ handle_notify (void *cls, struct GNUNET_SERVER_Client *client, | |||
628 | 710 | ||
629 | 711 | ||
630 | /** | 712 | /** |
631 | * FIXME. | 713 | * Release memory taken by a host entry. |
714 | * | ||
715 | * @param cls NULL | ||
716 | * @param key key of the host entry | ||
717 | * @param value the 'struct HostEntry' to free | ||
718 | * @return GNUNET_YES (continue to iterate) | ||
632 | */ | 719 | */ |
633 | static int | 720 | static int |
634 | free_host_entry (void *cls, const struct GNUNET_HashCode * key, void *value) | 721 | free_host_entry (void *cls, const struct GNUNET_HashCode * key, void *value) |
@@ -654,7 +741,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
654 | notify_list = NULL; | 741 | notify_list = NULL; |
655 | GNUNET_CONTAINER_multihashmap_iterate (hostmap, &free_host_entry, NULL); | 742 | GNUNET_CONTAINER_multihashmap_iterate (hostmap, &free_host_entry, NULL); |
656 | GNUNET_CONTAINER_multihashmap_destroy (hostmap); | 743 | GNUNET_CONTAINER_multihashmap_destroy (hostmap); |
657 | if (stats != NULL) | 744 | if (NULL != stats) |
658 | { | 745 | { |
659 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); | 746 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); |
660 | stats = NULL; | 747 | stats = NULL; |
@@ -685,6 +772,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
685 | }; | 772 | }; |
686 | char *peerdir; | 773 | char *peerdir; |
687 | char *ip; | 774 | char *ip; |
775 | struct DirScanContext dsc; | ||
688 | 776 | ||
689 | hostmap = GNUNET_CONTAINER_multihashmap_create (1024); | 777 | hostmap = GNUNET_CONTAINER_multihashmap_create (1024); |
690 | stats = GNUNET_STATISTICS_create ("peerinfo", cfg); | 778 | stats = GNUNET_STATISTICS_create ("peerinfo", cfg); |
@@ -709,8 +797,10 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
709 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 797 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
710 | _("Importing HELLOs from `%s'\n"), | 798 | _("Importing HELLOs from `%s'\n"), |
711 | peerdir); | 799 | peerdir); |
800 | dsc.matched = 0; | ||
801 | dsc.remove_files = GNUNET_NO; | ||
712 | GNUNET_DISK_directory_scan (peerdir, | 802 | GNUNET_DISK_directory_scan (peerdir, |
713 | &hosts_directory_scan_callback, NULL); | 803 | &hosts_directory_scan_callback, &dsc); |
714 | GNUNET_free (peerdir); | 804 | GNUNET_free (peerdir); |
715 | } | 805 | } |
716 | 806 | ||