diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-12-13 20:19:26 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-12-13 20:19:26 +0000 |
commit | 8723949c5796c40fe262b4843b4838dc0e67ae5c (patch) | |
tree | 4ae139f90f18ffed60b1321b5a47212133c0b1c6 /src/hostlist | |
parent | 7ee0e1af2fb61d09bdc646fbdbaa0a698330a478 (diff) | |
download | gnunet-8723949c5796c40fe262b4843b4838dc0e67ae5c.tar.gz gnunet-8723949c5796c40fe262b4843b4838dc0e67ae5c.zip |
properly clean up pending advertisement message requests with CORE on peer disconnect
Diffstat (limited to 'src/hostlist')
-rw-r--r-- | src/hostlist/gnunet-daemon-hostlist_server.c | 121 |
1 files changed, 90 insertions, 31 deletions
diff --git a/src/hostlist/gnunet-daemon-hostlist_server.c b/src/hostlist/gnunet-daemon-hostlist_server.c index c46bd371c..e090bfd87 100644 --- a/src/hostlist/gnunet-daemon-hostlist_server.c +++ b/src/hostlist/gnunet-daemon-hostlist_server.c | |||
@@ -101,17 +101,33 @@ static int advertising; | |||
101 | */ | 101 | */ |
102 | static char *hostlist_uri; | 102 | static char *hostlist_uri; |
103 | 103 | ||
104 | /** | ||
105 | * Map of peer identities to `struct GNUNET_CORE_TransmitHandle *` for | ||
106 | * pending hostlist server advertisements. | ||
107 | */ | ||
108 | static struct GNUNET_CONTAINER_MultiPeerMap *advertisements; | ||
109 | |||
104 | 110 | ||
105 | /** | 111 | /** |
106 | * Context for host processor. | 112 | * Context for #host_processor(). |
107 | */ | 113 | */ |
108 | struct HostSet | 114 | struct HostSet |
109 | { | 115 | { |
110 | unsigned int size; | 116 | /** |
117 | * Iterator used to build @e data (NULL when done). | ||
118 | */ | ||
119 | struct GNUNET_PEERINFO_IteratorContext *pitr; | ||
111 | 120 | ||
121 | /** | ||
122 | * Place where we accumulate all of the HELLO messages. | ||
123 | */ | ||
112 | char *data; | 124 | char *data; |
113 | 125 | ||
114 | struct GNUNET_PEERINFO_IteratorContext *pitr; | 126 | /** |
127 | * Number of bytes in @e data. | ||
128 | */ | ||
129 | unsigned int size; | ||
130 | |||
115 | }; | 131 | }; |
116 | 132 | ||
117 | 133 | ||
@@ -257,21 +273,26 @@ host_processor (void *cls, | |||
257 | (unsigned int) s, | 273 | (unsigned int) s, |
258 | "HELLO", | 274 | "HELLO", |
259 | GNUNET_i2s (peer)); | 275 | GNUNET_i2s (peer)); |
260 | if ((old + s >= GNUNET_MAX_MALLOC_CHECKED) || | 276 | if ( (old + s >= GNUNET_MAX_MALLOC_CHECKED) || |
261 | (old + s >= MAX_BYTES_PER_HOSTLISTS)) | 277 | (old + s >= MAX_BYTES_PER_HOSTLISTS) ) |
262 | { | 278 | { |
279 | /* too large, skip! */ | ||
263 | GNUNET_STATISTICS_update (stats, | 280 | GNUNET_STATISTICS_update (stats, |
264 | gettext_noop | 281 | gettext_noop |
265 | ("bytes not included in hostlist (size limit)"), | 282 | ("bytes not included in hostlist (size limit)"), |
266 | s, GNUNET_NO); | 283 | s, GNUNET_NO); |
267 | return; /* too large, skip! */ | 284 | return; |
268 | } | 285 | } |
269 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 286 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
270 | "Adding peer `%s' to hostlist (%u bytes)\n", | 287 | "Adding peer `%s' to hostlist (%u bytes)\n", |
271 | GNUNET_i2s (peer), | 288 | GNUNET_i2s (peer), |
272 | (unsigned int) s); | 289 | (unsigned int) s); |
273 | GNUNET_array_grow (builder->data, builder->size, old + s); | 290 | GNUNET_array_grow (builder->data, |
274 | memcpy (&builder->data[old], hello, s); | 291 | builder->size, |
292 | old + s); | ||
293 | memcpy (&builder->data[old], | ||
294 | hello, | ||
295 | s); | ||
275 | } | 296 | } |
276 | 297 | ||
277 | 298 | ||
@@ -436,14 +457,19 @@ adv_transmit_ready (void *cls, | |||
436 | header.type = htons (GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT); | 457 | header.type = htons (GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT); |
437 | header.size = htons (transmission_size); | 458 | header.size = htons (transmission_size); |
438 | GNUNET_assert (size >= transmission_size); | 459 | GNUNET_assert (size >= transmission_size); |
439 | memcpy (buf, &header, sizeof (struct GNUNET_MessageHeader)); | 460 | memcpy (buf, |
461 | &header, | ||
462 | sizeof (struct GNUNET_MessageHeader)); | ||
440 | cbuf = buf; | 463 | cbuf = buf; |
441 | memcpy (&cbuf[sizeof (struct GNUNET_MessageHeader)], hostlist_uri, uri_size); | 464 | memcpy (&cbuf[sizeof (struct GNUNET_MessageHeader)], |
465 | hostlist_uri, | ||
466 | uri_size); | ||
442 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 467 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
443 | "Sent advertisement message: Copied %u bytes into buffer!\n", | 468 | "Sent advertisement message: Copied %u bytes into buffer!\n", |
444 | (unsigned int) transmission_size); | 469 | (unsigned int) transmission_size); |
445 | hostlist_adv_count++; | 470 | hostlist_adv_count++; |
446 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " # Sent advertisement message: %u\n", | 471 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
472 | " # Sent advertisement message: %u\n", | ||
447 | hostlist_adv_count); | 473 | hostlist_adv_count); |
448 | GNUNET_STATISTICS_update (stats, | 474 | GNUNET_STATISTICS_update (stats, |
449 | gettext_noop ("# hostlist advertisements send"), 1, | 475 | gettext_noop ("# hostlist advertisements send"), 1, |
@@ -463,8 +489,9 @@ connect_handler (void *cls, | |||
463 | const struct GNUNET_PeerIdentity *peer) | 489 | const struct GNUNET_PeerIdentity *peer) |
464 | { | 490 | { |
465 | size_t size; | 491 | size_t size; |
492 | struct GNUNET_CORE_TransmitHandle *th; | ||
466 | 493 | ||
467 | if (!advertising) | 494 | if (! advertising) |
468 | return; | 495 | return; |
469 | if (NULL == hostlist_uri) | 496 | if (NULL == hostlist_uri) |
470 | return; | 497 | return; |
@@ -486,16 +513,21 @@ connect_handler (void *cls, | |||
486 | size, | 513 | size, |
487 | GNUNET_i2s (peer)); | 514 | GNUNET_i2s (peer)); |
488 | if (NULL == | 515 | if (NULL == |
489 | GNUNET_CORE_notify_transmit_ready (core, GNUNET_YES, | 516 | (th = GNUNET_CORE_notify_transmit_ready (core, GNUNET_YES, |
490 | GNUNET_CORE_PRIO_BEST_EFFORT, | 517 | GNUNET_CORE_PRIO_BEST_EFFORT, |
491 | GNUNET_ADV_TIMEOUT, | 518 | GNUNET_ADV_TIMEOUT, |
492 | peer, | 519 | peer, |
493 | size, | 520 | size, |
494 | &adv_transmit_ready, NULL)) | 521 | &adv_transmit_ready, NULL)) ) |
495 | { | 522 | { |
496 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 523 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
497 | _("Advertisement message could not be queued by core\n")); | 524 | _("Advertisement message could not be queued by core\n")); |
498 | } | 525 | } |
526 | GNUNET_assert (GNUNET_YES == | ||
527 | GNUNET_CONTAINER_multipeermap_put (advertisements, | ||
528 | peer, | ||
529 | th, | ||
530 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
499 | } | 531 | } |
500 | 532 | ||
501 | 533 | ||
@@ -509,9 +541,19 @@ static void | |||
509 | disconnect_handler (void *cls, | 541 | disconnect_handler (void *cls, |
510 | const struct GNUNET_PeerIdentity *peer) | 542 | const struct GNUNET_PeerIdentity *peer) |
511 | { | 543 | { |
512 | /* nothing to do */ | 544 | struct GNUNET_CORE_TransmitHandle *th; |
513 | /* FIXME: this is wrong, need to CANCEL active | 545 | |
514 | NTR! */ | 546 | if (! advertising) |
547 | return; | ||
548 | th = GNUNET_CONTAINER_multipeermap_get (advertisements, | ||
549 | peer); | ||
550 | if (NULL == th) | ||
551 | return; | ||
552 | GNUNET_assert (GNUNET_YES == | ||
553 | GNUNET_CONTAINER_multipeermap_remove (advertisements, | ||
554 | peer, | ||
555 | th)); | ||
556 | GNUNET_CORE_notify_transmit_ready_cancel (th); | ||
515 | } | 557 | } |
516 | 558 | ||
517 | 559 | ||
@@ -553,8 +595,10 @@ process_notify (void *cls, | |||
553 | builder = GNUNET_new (struct HostSet); | 595 | builder = GNUNET_new (struct HostSet); |
554 | } | 596 | } |
555 | GNUNET_assert (NULL != peerinfo); | 597 | GNUNET_assert (NULL != peerinfo); |
556 | builder->pitr = | 598 | builder->pitr |
557 | GNUNET_PEERINFO_iterate (peerinfo, GNUNET_NO, NULL, GNUNET_TIME_UNIT_MINUTES, | 599 | = GNUNET_PEERINFO_iterate (peerinfo, |
600 | GNUNET_NO, NULL, | ||
601 | GNUNET_TIME_UNIT_MINUTES, | ||
558 | &host_processor, NULL); | 602 | &host_processor, NULL); |
559 | } | 603 | } |
560 | 604 | ||
@@ -672,11 +716,17 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
672 | 716 | ||
673 | advertising = advertise; | 717 | advertising = advertise; |
674 | if (! advertising) | 718 | if (! advertising) |
719 | { | ||
675 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 720 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
676 | "Advertising not enabled on this hostlist server\n"); | 721 | "Advertising not enabled on this hostlist server\n"); |
722 | } | ||
677 | else | 723 | else |
724 | { | ||
678 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 725 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
679 | "Advertising enabled on this hostlist server\n"); | 726 | "Advertising enabled on this hostlist server\n"); |
727 | advertisements = GNUNET_CONTAINER_multipeermap_create (8, | ||
728 | GNUNET_NO); | ||
729 | } | ||
680 | cfg = c; | 730 | cfg = c; |
681 | stats = st; | 731 | stats = st; |
682 | peerinfo = GNUNET_PEERINFO_connect (cfg); | 732 | peerinfo = GNUNET_PEERINFO_connect (cfg); |
@@ -731,11 +781,11 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
731 | if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV4")) | 781 | if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV4")) |
732 | { | 782 | { |
733 | if (GNUNET_OK != | 783 | if (GNUNET_OK != |
734 | GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", | 784 | GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", |
735 | "BINDTOIP", &ipv4)) | 785 | "BINDTOIP", &ipv4)) |
736 | { | 786 | { |
737 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 787 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
738 | _("BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV4.\n")); | 788 | _("BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV4.\n")); |
739 | } | 789 | } |
740 | 790 | ||
741 | } | 791 | } |
@@ -744,9 +794,9 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
744 | if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV6")) | 794 | if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV6")) |
745 | { | 795 | { |
746 | if (GNUNET_OK != | 796 | if (GNUNET_OK != |
747 | GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", | 797 | GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", |
748 | "BINDTOIP", &ipv6)) | 798 | "BINDTOIP", &ipv6)) |
749 | { | 799 | { |
750 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 800 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
751 | _("BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV6.\n")); | 801 | _("BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV6.\n")); |
752 | } | 802 | } |
@@ -841,7 +891,8 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
841 | hostlist_task_v4 = prepare_daemon (daemon_handle_v4); | 891 | hostlist_task_v4 = prepare_daemon (daemon_handle_v4); |
842 | if (NULL != daemon_handle_v6) | 892 | if (NULL != daemon_handle_v6) |
843 | hostlist_task_v6 = prepare_daemon (daemon_handle_v6); | 893 | hostlist_task_v6 = prepare_daemon (daemon_handle_v6); |
844 | notify = GNUNET_PEERINFO_notify (cfg, GNUNET_NO, | 894 | notify = GNUNET_PEERINFO_notify (cfg, |
895 | GNUNET_NO, | ||
845 | &process_notify, NULL); | 896 | &process_notify, NULL); |
846 | return GNUNET_OK; | 897 | return GNUNET_OK; |
847 | } | 898 | } |
@@ -853,7 +904,8 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
853 | void | 904 | void |
854 | GNUNET_HOSTLIST_server_stop () | 905 | GNUNET_HOSTLIST_server_stop () |
855 | { | 906 | { |
856 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist server shutdown\n"); | 907 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
908 | "Hostlist server shutdown\n"); | ||
857 | if (GNUNET_SCHEDULER_NO_TASK != hostlist_task_v6) | 909 | if (GNUNET_SCHEDULER_NO_TASK != hostlist_task_v6) |
858 | { | 910 | { |
859 | GNUNET_SCHEDULER_cancel (hostlist_task_v6); | 911 | GNUNET_SCHEDULER_cancel (hostlist_task_v6); |
@@ -899,6 +951,13 @@ GNUNET_HOSTLIST_server_stop () | |||
899 | GNUNET_PEERINFO_disconnect (peerinfo); | 951 | GNUNET_PEERINFO_disconnect (peerinfo); |
900 | peerinfo = NULL; | 952 | peerinfo = NULL; |
901 | } | 953 | } |
954 | if (NULL != advertisements) | ||
955 | { | ||
956 | GNUNET_break (0 == | ||
957 | GNUNET_CONTAINER_multipeermap_size (advertisements)); | ||
958 | GNUNET_CONTAINER_multipeermap_destroy (advertisements); | ||
959 | advertisements = NULL; | ||
960 | } | ||
902 | cfg = NULL; | 961 | cfg = NULL; |
903 | stats = NULL; | 962 | stats = NULL; |
904 | core = NULL; | 963 | core = NULL; |