aboutsummaryrefslogtreecommitdiff
path: root/src/peerinfo
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-06-13 14:37:12 +0000
committerChristian Grothoff <christian@grothoff.org>2012-06-13 14:37:12 +0000
commit832d12049add37805697104b9f8eaae420eef406 (patch)
tree6f0214a2f7d6fff7761c1f2f3a0b0d4fcd2f2f26 /src/peerinfo
parentd2b611a870d2b6de2fe83b95a2497e062693d4d8 (diff)
downloadgnunet-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.c186
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 */
150static int
151count_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 */
185static struct GNUNET_HELLO_Message * 208static struct GNUNET_HELLO_Message *
186read_host_file (const char *fn) 209read_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 */
303struct 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)
271static int 329static int
272hosts_directory_scan_callback (void *cls, const char *fullname) 330hosts_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 */
596static int 678static int
597do_notify_entry (void *cls, const struct GNUNET_HashCode * key, void *value) 679do_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 */
633static int 720static int
634free_host_entry (void *cls, const struct GNUNET_HashCode * key, void *value) 721free_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