diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/peerinfo/gnunet-service-peerinfo.c | 381 |
1 files changed, 277 insertions, 104 deletions
diff --git a/src/peerinfo/gnunet-service-peerinfo.c b/src/peerinfo/gnunet-service-peerinfo.c index 26e54f320..32e50f348 100644 --- a/src/peerinfo/gnunet-service-peerinfo.c +++ b/src/peerinfo/gnunet-service-peerinfo.c | |||
@@ -88,6 +88,22 @@ struct TransmitContext | |||
88 | int friend_only; | 88 | int friend_only; |
89 | }; | 89 | }; |
90 | 90 | ||
91 | /** | ||
92 | * Result of reading a file | ||
93 | */ | ||
94 | struct ReadHostFileContext | ||
95 | { | ||
96 | /** | ||
97 | * Hello for the peer (can be NULL) | ||
98 | */ | ||
99 | struct GNUNET_HELLO_Message *hello; | ||
100 | |||
101 | /** | ||
102 | * Friend only hello for the peer (can be NULL) | ||
103 | */ | ||
104 | struct GNUNET_HELLO_Message *friend_only_hello; | ||
105 | }; | ||
106 | |||
91 | 107 | ||
92 | /** | 108 | /** |
93 | * Client notification context | 109 | * Client notification context |
@@ -156,18 +172,24 @@ static struct NotificationContext *nc_tail; | |||
156 | * @return generated notification message | 172 | * @return generated notification message |
157 | */ | 173 | */ |
158 | static struct InfoMessage * | 174 | static struct InfoMessage * |
159 | make_info_message (const struct HostEntry *he) | 175 | make_info_message (const struct HostEntry *he, int include_friend_only) |
160 | { | 176 | { |
161 | struct InfoMessage *im; | 177 | struct InfoMessage *im; |
178 | struct GNUNET_HELLO_Message *src; | ||
162 | size_t hs; | 179 | size_t hs; |
163 | 180 | ||
164 | hs = (NULL == he->hello) ? 0 : GNUNET_HELLO_size (he->hello); | 181 | if (GNUNET_YES == include_friend_only) |
182 | src = he->friend_only_hello; | ||
183 | else | ||
184 | src = he->hello; | ||
185 | |||
186 | hs = (NULL == src) ? 0 : GNUNET_HELLO_size (src); | ||
165 | im = GNUNET_malloc (sizeof (struct InfoMessage) + hs); | 187 | im = GNUNET_malloc (sizeof (struct InfoMessage) + hs); |
166 | im->header.size = htons (hs + sizeof (struct InfoMessage)); | 188 | im->header.size = htons (hs + sizeof (struct InfoMessage)); |
167 | im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO); | 189 | im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO); |
168 | im->peer = he->identity; | 190 | im->peer = he->identity; |
169 | if (he->hello != NULL) | 191 | if (NULL != src) |
170 | memcpy (&im[1], he->hello, hs); | 192 | memcpy (&im[1], src, hs); |
171 | return im; | 193 | return im; |
172 | } | 194 | } |
173 | 195 | ||
@@ -246,79 +268,155 @@ get_host_filename (const struct GNUNET_PeerIdentity *id) | |||
246 | static void | 268 | static void |
247 | notify_all (struct HostEntry *entry) | 269 | notify_all (struct HostEntry *entry) |
248 | { | 270 | { |
249 | struct InfoMessage *msg; | 271 | struct InfoMessage *msg_pub; |
272 | struct InfoMessage *msg_friend; | ||
250 | struct NotificationContext *cur; | 273 | struct NotificationContext *cur; |
251 | 274 | ||
252 | msg = make_info_message (entry); | 275 | msg_pub = make_info_message (entry, GNUNET_NO); |
276 | msg_friend = make_info_message (entry, GNUNET_YES); | ||
253 | 277 | ||
254 | for (cur = nc_head; NULL != cur; cur = cur->next) | 278 | for (cur = nc_head; NULL != cur; cur = cur->next) |
255 | { | 279 | { |
256 | if ((NULL != entry->hello) && | 280 | if (GNUNET_NO == cur->include_friend_only) |
257 | (GNUNET_YES == GNUNET_HELLO_is_friend_only (entry->hello)) && | 281 | GNUNET_SERVER_notification_context_unicast (notify_list, |
258 | (GNUNET_NO == cur->include_friend_only)) | 282 | cur->client, |
259 | continue; /* Friend only HELLO this client should not get */ | 283 | &msg_pub->header, |
260 | 284 | GNUNET_NO); | |
261 | GNUNET_SERVER_notification_context_unicast (notify_list, | 285 | if (GNUNET_YES == cur->include_friend_only) |
262 | cur->client, | 286 | GNUNET_SERVER_notification_context_unicast (notify_list, |
263 | &msg->header, | 287 | cur->client, |
264 | GNUNET_NO); | 288 | &msg_friend->header, |
289 | GNUNET_NO); | ||
265 | } | 290 | } |
266 | GNUNET_free (msg); | 291 | GNUNET_free (msg_pub); |
292 | GNUNET_free (msg_friend); | ||
267 | } | 293 | } |
268 | 294 | ||
269 | 295 | ||
270 | /** | 296 | /** |
271 | * Try to read the HELLO in the given filename and discard expired | 297 | * Try to read the HELLOs in the given filename and discard expired |
272 | * addresses. Removes the file if the HELLO is mal-formed. If all | 298 | * addresses. Removes the file if one the HELLO is mal-formed. If all |
273 | * addresses are expired, the HELLO is also removed (but the HELLO | 299 | * addresses are expired, the HELLO is also removed (but the HELLO |
274 | * with the public key is still returned if it was found and valid). | 300 | * with the public key is still returned if it was found and valid). |
275 | * | 301 | * |
276 | * @param fn name of the file | 302 | * @param fn name of the file |
277 | * @param unlink_garbage if GNUNET_YES, try to remove useless files | 303 | * @param unlink_garbage if GNUNET_YES, try to remove useless files |
278 | * @return HELLO of the file, NULL on error | ||
279 | */ | 304 | */ |
280 | static struct GNUNET_HELLO_Message * | 305 | static void |
281 | read_host_file (const char *fn, | 306 | read_host_file (const char *fn, int unlink_garbage, struct ReadHostFileContext *r) |
282 | int unlink_garbage) | ||
283 | { | 307 | { |
284 | char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; | 308 | char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; |
285 | const struct GNUNET_HELLO_Message *hello; | 309 | const struct GNUNET_HELLO_Message *hello_1st; |
286 | struct GNUNET_HELLO_Message *hello_clean; | 310 | const struct GNUNET_HELLO_Message *hello_2nd; |
287 | int size; | 311 | struct GNUNET_HELLO_Message *hello_clean_1st; |
312 | struct GNUNET_HELLO_Message *hello_clean_2nd; | ||
313 | int size_1st; | ||
314 | int size_2nd; | ||
315 | int size_total; | ||
288 | struct GNUNET_TIME_Absolute now; | 316 | struct GNUNET_TIME_Absolute now; |
289 | unsigned int left; | 317 | unsigned int left; |
290 | 318 | ||
319 | hello_1st = NULL; | ||
320 | hello_2nd = NULL; | ||
321 | hello_clean_1st = NULL; | ||
322 | hello_clean_2nd = NULL; | ||
323 | size_1st = 0; | ||
324 | size_2nd = 0; | ||
325 | size_total = 0; | ||
326 | r->friend_only_hello = NULL; | ||
327 | r->hello = NULL; | ||
328 | |||
291 | if (GNUNET_YES != GNUNET_DISK_file_test (fn)) | 329 | if (GNUNET_YES != GNUNET_DISK_file_test (fn)) |
292 | return NULL; | 330 | return; |
293 | size = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer)); | 331 | |
294 | hello = (const struct GNUNET_HELLO_Message *) buffer; | 332 | size_total = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer)); |
295 | if ((size < sizeof (struct GNUNET_MessageHeader)) || | 333 | if (size_total < sizeof (struct GNUNET_MessageHeader)) |
296 | (size != ntohs ((((const struct GNUNET_MessageHeader *) hello)->size))) | ||
297 | || (size != GNUNET_HELLO_size (hello))) | ||
298 | { | 334 | { |
299 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 335 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
300 | _("Failed to parse HELLO in file `%s'\n"), | 336 | _("Failed to parse HELLO in file `%s': %s\n"), |
301 | fn); | 337 | fn, "Fail has invalid size"); |
302 | if ( (GNUNET_YES == unlink_garbage) && | 338 | if ( (GNUNET_YES == unlink_garbage) && (0 != UNLINK (fn)) ) |
303 | (0 != UNLINK (fn)) ) | ||
304 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); | 339 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); |
305 | return NULL; | 340 | return; |
341 | } | ||
342 | |||
343 | hello_1st = (const struct GNUNET_HELLO_Message *) buffer; | ||
344 | size_1st = ntohs (((const struct GNUNET_MessageHeader *) hello_1st)->size); | ||
345 | if ((size_1st < sizeof (struct GNUNET_MessageHeader)) || | ||
346 | (size_1st != GNUNET_HELLO_size (hello_1st))) | ||
347 | { | ||
348 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
349 | _("Failed to parse HELLO in file `%s': %s\n"), | ||
350 | fn, "1nd HELLO has wrong size"); | ||
351 | if ((GNUNET_YES == unlink_garbage) && (0 != UNLINK (fn))) | ||
352 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); | ||
353 | return; | ||
354 | } | ||
355 | |||
356 | if (size_total > size_1st) | ||
357 | { | ||
358 | hello_2nd = (const struct GNUNET_HELLO_Message *) &buffer[size_1st]; | ||
359 | size_2nd = ntohs (((const struct GNUNET_MessageHeader *) hello_2nd)->size); | ||
360 | if ((size_2nd < sizeof (struct GNUNET_MessageHeader)) || | ||
361 | (size_2nd != GNUNET_HELLO_size (hello_2nd))) | ||
362 | { | ||
363 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
364 | _("Failed to parse HELLO in file `%s': %s\n"), | ||
365 | fn, "2nd HELLO has wrong size"); | ||
366 | if ((GNUNET_YES == unlink_garbage) && (0 != UNLINK (fn))) | ||
367 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); | ||
368 | return; | ||
369 | } | ||
306 | } | 370 | } |
371 | |||
372 | if (size_total != (size_1st + size_2nd)) | ||
373 | { | ||
374 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
375 | _("Failed to parse HELLO in file `%s': %s\n"), | ||
376 | fn, "Multiple HELLOs but total size is wrong"); | ||
377 | if ((GNUNET_YES == unlink_garbage) && (0 != UNLINK (fn))) | ||
378 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); | ||
379 | return; | ||
380 | } | ||
381 | |||
307 | now = GNUNET_TIME_absolute_get (); | 382 | now = GNUNET_TIME_absolute_get (); |
308 | hello_clean = | 383 | |
309 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES, &discard_expired, | 384 | hello_clean_1st = GNUNET_HELLO_iterate_addresses (hello_1st, GNUNET_YES, |
310 | &now); | 385 | &discard_expired, &now); |
311 | left = 0; | 386 | left = 0; |
312 | (void) GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &count_addresses, | 387 | (void) GNUNET_HELLO_iterate_addresses (hello_1st, GNUNET_NO, |
313 | &left); | 388 | &count_addresses, &left); |
314 | if (0 == left) | 389 | if (0 == left) |
315 | { | 390 | { |
316 | /* no addresses left, remove from disk */ | 391 | /* no addresses left, remove from disk */ |
317 | if ( (GNUNET_YES == unlink_garbage) && | 392 | if ((GNUNET_YES == unlink_garbage) && (0 != UNLINK (fn))) |
318 | (0 != UNLINK (fn)) ) | ||
319 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); | 393 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); |
320 | } | 394 | } |
321 | return hello_clean; | 395 | |
396 | if (GNUNET_NO == GNUNET_HELLO_is_friend_only(hello_clean_1st)) | ||
397 | r->hello = hello_clean_1st; | ||
398 | else | ||
399 | r->friend_only_hello = hello_clean_1st; | ||
400 | |||
401 | if (NULL != hello_2nd) | ||
402 | { | ||
403 | hello_clean_2nd = GNUNET_HELLO_iterate_addresses (hello_2nd, GNUNET_YES, | ||
404 | &discard_expired, &now); | ||
405 | left = 0; | ||
406 | (void) GNUNET_HELLO_iterate_addresses (hello_2nd, GNUNET_NO, | ||
407 | &count_addresses, &left); | ||
408 | if (0 == left) | ||
409 | { | ||
410 | /* no addresses left, remove from disk */ | ||
411 | if ((GNUNET_YES == unlink_garbage) && (0 != UNLINK (fn))) | ||
412 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); | ||
413 | } | ||
414 | |||
415 | if (GNUNET_NO == GNUNET_HELLO_is_friend_only(hello_clean_2nd)) | ||
416 | r->hello = hello_clean_2nd; | ||
417 | else | ||
418 | r->friend_only_hello = hello_clean_2nd; | ||
419 | } | ||
322 | } | 420 | } |
323 | 421 | ||
324 | 422 | ||
@@ -331,6 +429,7 @@ static void | |||
331 | add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity) | 429 | add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity) |
332 | { | 430 | { |
333 | struct HostEntry *entry; | 431 | struct HostEntry *entry; |
432 | struct ReadHostFileContext r; | ||
334 | char *fn; | 433 | char *fn; |
335 | 434 | ||
336 | entry = GNUNET_CONTAINER_multihashmap_get (hostmap, &identity->hashPubKey); | 435 | entry = GNUNET_CONTAINER_multihashmap_get (hostmap, &identity->hashPubKey); |
@@ -345,7 +444,9 @@ add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity) | |||
345 | fn = get_host_filename (identity); | 444 | fn = get_host_filename (identity); |
346 | if (NULL != fn) | 445 | if (NULL != fn) |
347 | { | 446 | { |
348 | entry->hello = read_host_file (fn, GNUNET_YES); | 447 | read_host_file (fn, GNUNET_YES, &r); |
448 | entry->hello = r.hello; | ||
449 | entry->hello = r.friend_only_hello; | ||
349 | GNUNET_free (fn); | 450 | GNUNET_free (fn); |
350 | } | 451 | } |
351 | notify_all (entry); | 452 | notify_all (entry); |
@@ -406,10 +507,11 @@ hosts_directory_scan_callback (void *cls, const char *fullname) | |||
406 | { | 507 | { |
407 | struct DirScanContext *dsc = cls; | 508 | struct DirScanContext *dsc = cls; |
408 | struct GNUNET_PeerIdentity identity; | 509 | struct GNUNET_PeerIdentity identity; |
510 | struct ReadHostFileContext r; | ||
409 | const char *filename; | 511 | const char *filename; |
410 | struct HostEntry *entry; | 512 | struct HostEntry *entry; |
411 | struct GNUNET_HELLO_Message *hello; | 513 | struct GNUNET_PeerIdentity id_public; |
412 | struct GNUNET_PeerIdentity id; | 514 | struct GNUNET_PeerIdentity id_friend; |
413 | 515 | ||
414 | if (GNUNET_YES != GNUNET_DISK_file_test (fullname)) | 516 | if (GNUNET_YES != GNUNET_DISK_file_test (fullname)) |
415 | return GNUNET_OK; /* ignore non-files */ | 517 | return GNUNET_OK; /* ignore non-files */ |
@@ -432,20 +534,32 @@ hosts_directory_scan_callback (void *cls, const char *fullname) | |||
432 | GNUNET_CRYPTO_hash_from_string (filename, &identity.hashPubKey)) | 534 | GNUNET_CRYPTO_hash_from_string (filename, &identity.hashPubKey)) |
433 | { | 535 | { |
434 | /* odd filename, but might still be valid, try getting identity from HELLO */ | 536 | /* odd filename, but might still be valid, try getting identity from HELLO */ |
435 | if ( (NULL != (hello = read_host_file (filename, | 537 | read_host_file (filename, dsc->remove_files, &r); |
436 | dsc->remove_files))) && | 538 | if ( ((NULL != r.hello) && |
437 | (GNUNET_OK == | 539 | (GNUNET_OK == GNUNET_HELLO_get_id (r.hello, &id_public))) || |
438 | GNUNET_HELLO_get_id (hello, | 540 | ((NULL != r.friend_only_hello) && |
439 | &id)) ) | 541 | (GNUNET_OK == GNUNET_HELLO_get_id (r.friend_only_hello, &id_friend))) ) |
440 | { | 542 | { |
441 | /* ok, found something valid, remember HELLO */ | 543 | if ( (NULL != r.hello) && (NULL != r.friend_only_hello) && |
544 | (0 != memcmp (&id_friend, &id_public, sizeof (id_friend))) ) | ||
545 | { | ||
546 | /* HELLOs are not for the same peer */ | ||
547 | GNUNET_break (0); | ||
548 | if (GNUNET_YES == dsc->remove_files) | ||
549 | remove_garbage (fullname); | ||
550 | return GNUNET_OK; | ||
551 | } | ||
552 | |||
553 | /* ok, found something valid, remember HELLO */ | ||
442 | entry = GNUNET_malloc (sizeof (struct HostEntry)); | 554 | entry = GNUNET_malloc (sizeof (struct HostEntry)); |
443 | entry->identity = id; | 555 | entry->identity = id_friend; |
444 | GNUNET_CONTAINER_multihashmap_put (hostmap, &entry->identity.hashPubKey, entry, | 556 | GNUNET_CONTAINER_multihashmap_put (hostmap, &entry->identity.hashPubKey, entry, |
445 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 557 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); |
446 | entry->hello = hello; | 558 | entry->hello = r.hello; |
447 | notify_all (entry); | 559 | entry->hello = r.friend_only_hello; |
448 | dsc->matched++; | 560 | notify_all (entry); |
561 | dsc->matched++; | ||
562 | |||
449 | return GNUNET_OK; | 563 | return GNUNET_OK; |
450 | } | 564 | } |
451 | if (GNUNET_YES == dsc->remove_files) | 565 | if (GNUNET_YES == dsc->remove_files) |
@@ -494,6 +608,29 @@ cron_scan_directory_data_hosts (void *cls, | |||
494 | } | 608 | } |
495 | 609 | ||
496 | 610 | ||
611 | static struct GNUNET_HELLO_Message * | ||
612 | update_friend_hello (const struct GNUNET_HELLO_Message *hello, | ||
613 | const struct GNUNET_HELLO_Message *friend_hello) | ||
614 | { | ||
615 | struct GNUNET_HELLO_Message * res; | ||
616 | struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded pk; | ||
617 | |||
618 | if (NULL != friend_hello) | ||
619 | { | ||
620 | res = GNUNET_HELLO_merge (hello, friend_hello); | ||
621 | GNUNET_assert (GNUNET_YES == GNUNET_HELLO_is_friend_only (res)); | ||
622 | return res; | ||
623 | } | ||
624 | |||
625 | GNUNET_HELLO_get_key (hello, &pk); | ||
626 | res = GNUNET_HELLO_create (&pk, NULL, NULL, GNUNET_YES); | ||
627 | res = GNUNET_HELLO_merge (hello, res); | ||
628 | GNUNET_assert (GNUNET_YES == GNUNET_HELLO_is_friend_only (res)); | ||
629 | return res; | ||
630 | } | ||
631 | |||
632 | |||
633 | |||
497 | /** | 634 | /** |
498 | * Bind a host address (hello) to a hostId. | 635 | * Bind a host address (hello) to a hostId. |
499 | * | 636 | * |
@@ -507,59 +644,77 @@ bind_address (const struct GNUNET_PeerIdentity *peer, | |||
507 | char *fn; | 644 | char *fn; |
508 | struct HostEntry *host; | 645 | struct HostEntry *host; |
509 | struct GNUNET_HELLO_Message *mrg; | 646 | struct GNUNET_HELLO_Message *mrg; |
647 | struct GNUNET_HELLO_Message **dest; | ||
510 | struct GNUNET_TIME_Absolute delta; | 648 | struct GNUNET_TIME_Absolute delta; |
511 | unsigned int cnt; | 649 | unsigned int cnt; |
650 | int friend_hello_type; | ||
512 | 651 | ||
513 | add_host_to_known_hosts (peer); | 652 | add_host_to_known_hosts (peer); |
514 | host = GNUNET_CONTAINER_multihashmap_get (hostmap, &peer->hashPubKey); | 653 | host = GNUNET_CONTAINER_multihashmap_get (hostmap, &peer->hashPubKey); |
515 | GNUNET_assert (NULL != host); | 654 | GNUNET_assert (NULL != host); |
516 | if (NULL == host->hello) | 655 | friend_hello_type = GNUNET_HELLO_is_friend_only (hello); |
656 | |||
657 | dest = NULL; | ||
658 | if (GNUNET_YES == friend_hello_type) | ||
517 | { | 659 | { |
518 | host->hello = GNUNET_malloc (GNUNET_HELLO_size (hello)); | 660 | dest = &host->friend_only_hello; |
519 | memcpy (host->hello, hello, GNUNET_HELLO_size (hello)); | ||
520 | } | 661 | } |
521 | else | 662 | else |
522 | { | 663 | { |
664 | dest = &host->hello; | ||
665 | } | ||
523 | 666 | ||
524 | if (GNUNET_HELLO_is_friend_only (host->hello) != GNUNET_HELLO_is_friend_only (hello)) | 667 | if (NULL == (*dest)) |
525 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 668 | { |
526 | "Merging public with friend only HELLO, result will be friend-only!\n"); | 669 | (*dest) = GNUNET_malloc (GNUNET_HELLO_size (hello)); |
527 | mrg = GNUNET_HELLO_merge (host->hello, hello); | 670 | memcpy ((*dest), hello, GNUNET_HELLO_size (hello)); |
528 | delta = GNUNET_HELLO_equals (mrg, host->hello, GNUNET_TIME_absolute_get ()); | 671 | } |
672 | else | ||
673 | { | ||
674 | mrg = GNUNET_HELLO_merge ((*dest), hello); | ||
675 | delta = GNUNET_HELLO_equals (mrg, (*dest), GNUNET_TIME_absolute_get ()); | ||
529 | if (delta.abs_value == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value) | 676 | if (delta.abs_value == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value) |
530 | { | 677 | { |
531 | /* no differences, just ignore the update */ | 678 | /* no differences, just ignore the update */ |
532 | GNUNET_free (mrg); | 679 | GNUNET_free (mrg); |
533 | return; | 680 | return; |
534 | } | 681 | } |
535 | GNUNET_free (host->hello); | 682 | GNUNET_free ((*dest)); |
536 | host->hello = mrg; | 683 | (*dest) = mrg; |
537 | } | 684 | } |
538 | fn = get_host_filename (peer); | 685 | |
539 | if ( (NULL != fn) && | 686 | if ((NULL != (host->hello)) && (GNUNET_NO == friend_hello_type)) |
540 | (GNUNET_OK == GNUNET_DISK_directory_create_for_file (fn)) ) | 687 | host->friend_only_hello = update_friend_hello (host->hello, host->friend_only_hello); |
541 | { | 688 | |
542 | cnt = 0; | 689 | fn = get_host_filename (peer); |
543 | (void) GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &count_addresses, | 690 | if ( (NULL != fn) && |
544 | &cnt); | 691 | (GNUNET_OK == GNUNET_DISK_directory_create_for_file (fn)) ) |
545 | if (0 == cnt) | 692 | { |
546 | { | 693 | #if 0 |
547 | /* no valid addresses, don't put HELLO on disk; in fact, | 694 | cnt = 0; |
548 | if one exists on disk, remove it */ | 695 | (void) GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &count_addresses, |
549 | (void) UNLINK (fn); | 696 | &cnt); |
550 | } | 697 | if (0 == cnt) |
551 | else | 698 | { |
552 | { | 699 | /* no valid addresses, don't put HELLO on disk; in fact, |
553 | if (GNUNET_SYSERR == | 700 | if one exists on disk, remove it */ |
554 | GNUNET_DISK_fn_write (fn, host->hello, GNUNET_HELLO_size (host->hello), | 701 | (void) UNLINK (fn); |
555 | GNUNET_DISK_PERM_USER_READ | | 702 | } |
556 | GNUNET_DISK_PERM_USER_WRITE | | 703 | else |
557 | GNUNET_DISK_PERM_GROUP_READ | | 704 | { |
558 | GNUNET_DISK_PERM_OTHER_READ)) | 705 | if (GNUNET_SYSERR == |
559 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn); | 706 | GNUNET_DISK_fn_write (fn, host->hello, GNUNET_HELLO_size (host->hello), |
560 | } | 707 | GNUNET_DISK_PERM_USER_READ | |
708 | GNUNET_DISK_PERM_USER_WRITE | | ||
709 | GNUNET_DISK_PERM_GROUP_READ | | ||
710 | GNUNET_DISK_PERM_OTHER_READ)) | ||
711 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn); | ||
712 | } | ||
713 | } | ||
714 | #endif | ||
715 | GNUNET_free_non_null (fn); | ||
561 | } | 716 | } |
562 | GNUNET_free_non_null (fn); | 717 | |
563 | notify_all (host); | 718 | notify_all (host); |
564 | } | 719 | } |
565 | 720 | ||
@@ -583,15 +738,25 @@ add_to_tc (void *cls, const struct GNUNET_HashCode * key, void *value) | |||
583 | 738 | ||
584 | hs = 0; | 739 | hs = 0; |
585 | im = (struct InfoMessage *) buf; | 740 | im = (struct InfoMessage *) buf; |
586 | if ((pos->hello != NULL) && | 741 | |
587 | ((GNUNET_NO == GNUNET_HELLO_is_friend_only (pos->hello)) || | 742 | if ((pos->hello != NULL) && (GNUNET_NO == tc->friend_only)) |
588 | ((GNUNET_YES == GNUNET_HELLO_is_friend_only (pos->hello)) && (GNUNET_YES == tc->friend_only)))) | ||
589 | { | 743 | { |
744 | /* Copy public HELLO */ | ||
590 | hs = GNUNET_HELLO_size (pos->hello); | 745 | hs = GNUNET_HELLO_size (pos->hello); |
591 | GNUNET_assert (hs < | 746 | GNUNET_assert (hs < GNUNET_SERVER_MAX_MESSAGE_SIZE - |
592 | GNUNET_SERVER_MAX_MESSAGE_SIZE - | ||
593 | sizeof (struct InfoMessage)); | 747 | sizeof (struct InfoMessage)); |
594 | memcpy (&im[1], pos->hello, hs); | 748 | memcpy (&im[1], pos->hello, hs); |
749 | |||
750 | } | ||
751 | |||
752 | if ((pos->friend_only_hello != NULL) && (GNUNET_YES == tc->friend_only)) | ||
753 | { | ||
754 | /* Copy friend only HELLO */ | ||
755 | hs = GNUNET_HELLO_size (pos->friend_only_hello); | ||
756 | GNUNET_assert (hs < GNUNET_SERVER_MAX_MESSAGE_SIZE - | ||
757 | sizeof (struct InfoMessage)); | ||
758 | memcpy (&im[1], pos->friend_only_hello, hs); | ||
759 | |||
595 | } | 760 | } |
596 | im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO); | 761 | im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO); |
597 | im->header.size = htons (sizeof (struct InfoMessage) + hs); | 762 | im->header.size = htons (sizeof (struct InfoMessage) + hs); |
@@ -603,7 +768,7 @@ add_to_tc (void *cls, const struct GNUNET_HashCode * key, void *value) | |||
603 | 768 | ||
604 | 769 | ||
605 | /** | 770 | /** |
606 | * @brief delete expired HELLO entries in data/hosts/ | 771 | * @brief delete expired HELLO entries in directory |
607 | * | 772 | * |
608 | * @param cls pointer to current time (struct GNUNET_TIME_Absolute) | 773 | * @param cls pointer to current time (struct GNUNET_TIME_Absolute) |
609 | * @param fn filename to test to see if the HELLO expired | 774 | * @param fn filename to test to see if the HELLO expired |
@@ -753,6 +918,7 @@ handle_get_all (void *cls, struct GNUNET_SERVER_Client *client, | |||
753 | } | 918 | } |
754 | 919 | ||
755 | 920 | ||
921 | |||
756 | /** | 922 | /** |
757 | * Pass the given client the information we have in the respective | 923 | * Pass the given client the information we have in the respective |
758 | * host entry; the client is already in the notification context. | 924 | * host entry; the client is already in the notification context. |
@@ -769,15 +935,21 @@ do_notify_entry (void *cls, const struct GNUNET_HashCode * key, void *value) | |||
769 | struct HostEntry *he = value; | 935 | struct HostEntry *he = value; |
770 | struct InfoMessage *msg; | 936 | struct InfoMessage *msg; |
771 | 937 | ||
772 | if ((NULL != he->hello) && | 938 | |
773 | (GNUNET_YES == GNUNET_HELLO_is_friend_only(he->hello)) && | 939 | if ((NULL == he->hello) && (GNUNET_NO == nc->include_friend_only)) |
774 | (GNUNET_NO == nc->include_friend_only)) | 940 | { |
941 | /* We have no public hello */ | ||
942 | return GNUNET_YES; | ||
943 | } | ||
944 | |||
945 | |||
946 | if ((NULL == he->friend_only_hello) && GNUNET_YES == nc->include_friend_only) | ||
775 | { | 947 | { |
776 | /* We have a friend only hello and a client not interested, continue */ | 948 | /* We have no friend hello */ |
777 | return GNUNET_YES; | 949 | return GNUNET_YES; |
778 | } | 950 | } |
779 | 951 | ||
780 | msg = make_info_message (he); | 952 | msg = make_info_message (he, nc->include_friend_only); |
781 | GNUNET_SERVER_notification_context_unicast (notify_list, | 953 | GNUNET_SERVER_notification_context_unicast (notify_list, |
782 | nc->client, | 954 | nc->client, |
783 | &msg->header, | 955 | &msg->header, |
@@ -851,6 +1023,7 @@ free_host_entry (void *cls, const struct GNUNET_HashCode * key, void *value) | |||
851 | struct HostEntry *he = value; | 1023 | struct HostEntry *he = value; |
852 | 1024 | ||
853 | GNUNET_free_non_null (he->hello); | 1025 | GNUNET_free_non_null (he->hello); |
1026 | GNUNET_free_non_null (he->friend_only_hello); | ||
854 | GNUNET_free (he); | 1027 | GNUNET_free (he); |
855 | return GNUNET_YES; | 1028 | return GNUNET_YES; |
856 | } | 1029 | } |