diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2013-12-18 08:57:03 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2013-12-18 08:57:03 +0000 |
commit | ba6439dcf325a3e6e598c034e60815f39646562b (patch) | |
tree | df633a1005504e92bb3abfdbc7623d968e1cf844 /src | |
parent | 7f7906e96922d1f0410439ad08b3900937186ca5 (diff) | |
download | gnunet-ba6439dcf325a3e6e598c034e60815f39646562b.tar.gz gnunet-ba6439dcf325a3e6e598c034e60815f39646562b.zip |
fixing 0003221: Crash in UDP broadcast: plugin_transport_udp_broadcasting.c:253.
Diffstat (limited to 'src')
-rw-r--r-- | src/transport/plugin_transport_udp.c | 24 | ||||
-rw-r--r-- | src/transport/plugin_transport_udp.h | 5 | ||||
-rw-r--r-- | src/transport/plugin_transport_udp_broadcasting.c | 73 |
3 files changed, 56 insertions, 46 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index bdf10c197..43c46aae7 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c | |||
@@ -2499,7 +2499,7 @@ udp_select_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) | |||
2499 | switch (ntohs (msg->type)) | 2499 | switch (ntohs (msg->type)) |
2500 | { | 2500 | { |
2501 | case GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON: | 2501 | case GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON: |
2502 | udp_broadcast_receive (plugin, buf, size, | 2502 | udp_broadcast_receive (plugin, buf, size, |
2503 | (const struct sockaddr *) &addr, fromlen); | 2503 | (const struct sockaddr *) &addr, fromlen); |
2504 | return; | 2504 | return; |
2505 | case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE: | 2505 | case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE: |
@@ -3030,9 +3030,9 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
3030 | struct Plugin *p; | 3030 | struct Plugin *p; |
3031 | unsigned long long port; | 3031 | unsigned long long port; |
3032 | unsigned long long aport; | 3032 | unsigned long long aport; |
3033 | unsigned long long broadcast; | ||
3034 | unsigned long long udp_max_bps; | 3033 | unsigned long long udp_max_bps; |
3035 | unsigned long long enable_v6; | 3034 | unsigned long long enable_v6; |
3035 | unsigned long long enable_broadcasting; | ||
3036 | char * bind4_address; | 3036 | char * bind4_address; |
3037 | char * bind6_address; | 3037 | char * bind6_address; |
3038 | char * fancy_interval; | 3038 | char * fancy_interval; |
@@ -3126,10 +3126,10 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
3126 | myoptions = 0; | 3126 | myoptions = 0; |
3127 | 3127 | ||
3128 | /* Enable neighbour discovery */ | 3128 | /* Enable neighbour discovery */ |
3129 | broadcast = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, "transport-udp", | 3129 | enable_broadcasting = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, "transport-udp", |
3130 | "BROADCAST"); | 3130 | "BROADCAST"); |
3131 | if (broadcast == GNUNET_SYSERR) | 3131 | if (enable_broadcasting == GNUNET_SYSERR) |
3132 | broadcast = GNUNET_NO; | 3132 | enable_broadcasting = GNUNET_NO; |
3133 | 3133 | ||
3134 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (env->cfg, "transport-udp", | 3134 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (env->cfg, "transport-udp", |
3135 | "BROADCAST_INTERVAL", &fancy_interval)) | 3135 | "BROADCAST_INTERVAL", &fancy_interval)) |
@@ -3158,6 +3158,7 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
3158 | p->broadcast_interval = interval; | 3158 | p->broadcast_interval = interval; |
3159 | p->enable_ipv6 = enable_v6; | 3159 | p->enable_ipv6 = enable_v6; |
3160 | p->enable_ipv4 = GNUNET_YES; /* default */ | 3160 | p->enable_ipv4 = GNUNET_YES; /* default */ |
3161 | p->enable_broadcasting = enable_broadcasting; | ||
3161 | p->env = env; | 3162 | p->env = env; |
3162 | p->sessions = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); | 3163 | p->sessions = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); |
3163 | p->defrag_ctxs = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | 3164 | p->defrag_ctxs = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); |
@@ -3179,11 +3180,9 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
3179 | GNUNET_free (p); | 3180 | GNUNET_free (p); |
3180 | return NULL; | 3181 | return NULL; |
3181 | } | 3182 | } |
3182 | else if (broadcast == GNUNET_YES) | 3183 | |
3183 | { | 3184 | /* Setup broadcasting and receiving beacons */ |
3184 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting broadcasting\n"); | 3185 | setup_broadcast (p, &server_addrv6, &server_addrv4); |
3185 | setup_broadcast (p, &server_addrv6, &server_addrv4); | ||
3186 | } | ||
3187 | 3186 | ||
3188 | api = GNUNET_new (struct GNUNET_TRANSPORT_PluginFunctions); | 3187 | api = GNUNET_new (struct GNUNET_TRANSPORT_PluginFunctions); |
3189 | api->cls = p; | 3188 | api->cls = p; |
@@ -3286,11 +3285,6 @@ libgnunet_plugin_transport_udp_done (void *cls) | |||
3286 | GNUNET_CONTAINER_heap_destroy (plugin->defrag_ctxs); | 3285 | GNUNET_CONTAINER_heap_destroy (plugin->defrag_ctxs); |
3287 | plugin->defrag_ctxs = NULL; | 3286 | plugin->defrag_ctxs = NULL; |
3288 | } | 3287 | } |
3289 | if (plugin->mst != NULL) | ||
3290 | { | ||
3291 | GNUNET_SERVER_mst_destroy(plugin->mst); | ||
3292 | plugin->mst = NULL; | ||
3293 | } | ||
3294 | 3288 | ||
3295 | /* Clean up leftover messages */ | 3289 | /* Clean up leftover messages */ |
3296 | struct UDP_MessageWrapper * udpw; | 3290 | struct UDP_MessageWrapper * udpw; |
diff --git a/src/transport/plugin_transport_udp.h b/src/transport/plugin_transport_udp.h index 0ca596861..2873266b5 100644 --- a/src/transport/plugin_transport_udp.h +++ b/src/transport/plugin_transport_udp.h | |||
@@ -249,6 +249,11 @@ struct Plugin | |||
249 | int enable_ipv4; | 249 | int enable_ipv4; |
250 | 250 | ||
251 | /** | 251 | /** |
252 | * Is broadcasting enabled: GNUNET_YES or GNUNET_NO | ||
253 | */ | ||
254 | int enable_broadcasting; | ||
255 | |||
256 | /** | ||
252 | * Port we broadcasting on. | 257 | * Port we broadcasting on. |
253 | */ | 258 | */ |
254 | uint16_t broadcast_port; | 259 | uint16_t broadcast_port; |
diff --git a/src/transport/plugin_transport_udp_broadcasting.c b/src/transport/plugin_transport_udp_broadcasting.c index 35c2a0ea5..61ac3d10e 100644 --- a/src/transport/plugin_transport_udp_broadcasting.c +++ b/src/transport/plugin_transport_udp_broadcasting.c | |||
@@ -612,6 +612,10 @@ setup_broadcast (struct Plugin *plugin, | |||
612 | GNUNET_SERVER_mst_create (&broadcast_ipv4_mst_cb, plugin); | 612 | GNUNET_SERVER_mst_create (&broadcast_ipv4_mst_cb, plugin); |
613 | plugin->broadcast_ipv6_mst = | 613 | plugin->broadcast_ipv6_mst = |
614 | GNUNET_SERVER_mst_create (&broadcast_ipv6_mst_cb, plugin); | 614 | GNUNET_SERVER_mst_create (&broadcast_ipv6_mst_cb, plugin); |
615 | |||
616 | if (GNUNET_YES != plugin->enable_broadcasting) | ||
617 | return; /* We do not send, just receive */ | ||
618 | |||
615 | /* create IPv4 broadcast socket */ | 619 | /* create IPv4 broadcast socket */ |
616 | if ((GNUNET_YES == plugin->enable_ipv4) && (NULL != plugin->sockv4)) | 620 | if ((GNUNET_YES == plugin->enable_ipv4) && (NULL != plugin->sockv4)) |
617 | { | 621 | { |
@@ -626,6 +630,7 @@ setup_broadcast (struct Plugin *plugin, | |||
626 | ntohs (server_addrv4->sin_port)); | 630 | ntohs (server_addrv4->sin_port)); |
627 | } | 631 | } |
628 | } | 632 | } |
633 | /* create IPv6 multicast socket */ | ||
629 | if ((GNUNET_YES == plugin->enable_ipv6) && (plugin->sockv6 != NULL)) | 634 | if ((GNUNET_YES == plugin->enable_ipv6) && (plugin->sockv6 != NULL)) |
630 | { | 635 | { |
631 | memset (&plugin->ipv6_multicast_address, 0, sizeof (struct sockaddr_in6)); | 636 | memset (&plugin->ipv6_multicast_address, 0, sizeof (struct sockaddr_in6)); |
@@ -642,49 +647,55 @@ setup_broadcast (struct Plugin *plugin, | |||
642 | void | 647 | void |
643 | stop_broadcast (struct Plugin *plugin) | 648 | stop_broadcast (struct Plugin *plugin) |
644 | { | 649 | { |
645 | while (plugin->broadcast_head != NULL) | 650 | if (GNUNET_YES == plugin->enable_broadcasting) |
646 | { | 651 | { |
647 | struct BroadcastAddress *p = plugin->broadcast_head; | 652 | /* Disable broadcasting */ |
648 | 653 | while (plugin->broadcast_head != NULL) | |
649 | if (p->broadcast_task != GNUNET_SCHEDULER_NO_TASK) | ||
650 | { | 654 | { |
651 | GNUNET_SCHEDULER_cancel (p->broadcast_task); | 655 | struct BroadcastAddress *p = plugin->broadcast_head; |
652 | p->broadcast_task = GNUNET_SCHEDULER_NO_TASK; | ||
653 | } | ||
654 | if ((GNUNET_YES == plugin->enable_ipv6) && | ||
655 | (NULL != plugin->sockv6) && | ||
656 | (p->addrlen == sizeof (struct sockaddr_in6))) | ||
657 | { | ||
658 | /* Create IPv6 multicast request */ | ||
659 | struct ipv6_mreq multicastRequest; | ||
660 | const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) p->addr; | ||
661 | 656 | ||
662 | multicastRequest.ipv6mr_multiaddr = | 657 | if (p->broadcast_task != GNUNET_SCHEDULER_NO_TASK) |
663 | plugin->ipv6_multicast_address.sin6_addr; | ||
664 | multicastRequest.ipv6mr_interface = s6->sin6_scope_id; | ||
665 | |||
666 | /* Leave the multicast group */ | ||
667 | if (GNUNET_OK == | ||
668 | GNUNET_NETWORK_socket_setsockopt | ||
669 | (plugin->sockv6, IPPROTO_IPV6, IPV6_LEAVE_GROUP, | ||
670 | &multicastRequest, sizeof (multicastRequest))) | ||
671 | { | 658 | { |
672 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, setsockopt); | 659 | GNUNET_SCHEDULER_cancel (p->broadcast_task); |
660 | p->broadcast_task = GNUNET_SCHEDULER_NO_TASK; | ||
673 | } | 661 | } |
674 | else | 662 | if ((GNUNET_YES == plugin->enable_ipv6) && |
663 | (NULL != plugin->sockv6) && | ||
664 | (p->addrlen == sizeof (struct sockaddr_in6))) | ||
675 | { | 665 | { |
676 | LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv6 multicasting stopped\n"); | 666 | /* Create IPv6 multicast request */ |
667 | struct ipv6_mreq multicastRequest; | ||
668 | const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) p->addr; | ||
669 | |||
670 | multicastRequest.ipv6mr_multiaddr = | ||
671 | plugin->ipv6_multicast_address.sin6_addr; | ||
672 | multicastRequest.ipv6mr_interface = s6->sin6_scope_id; | ||
673 | |||
674 | /* Leave the multicast group */ | ||
675 | if (GNUNET_OK == | ||
676 | GNUNET_NETWORK_socket_setsockopt | ||
677 | (plugin->sockv6, IPPROTO_IPV6, IPV6_LEAVE_GROUP, | ||
678 | &multicastRequest, sizeof (multicastRequest))) | ||
679 | { | ||
680 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, setsockopt); | ||
681 | } | ||
682 | else | ||
683 | { | ||
684 | LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv6 multicasting stopped\n"); | ||
685 | } | ||
677 | } | 686 | } |
678 | } | ||
679 | 687 | ||
680 | #if LINUX | 688 | #if LINUX |
681 | GNUNET_DISK_file_close(p->cryogenic_fd); | 689 | GNUNET_DISK_file_close(p->cryogenic_fd); |
682 | #endif | 690 | #endif |
683 | GNUNET_CONTAINER_DLL_remove (plugin->broadcast_head, | 691 | GNUNET_CONTAINER_DLL_remove (plugin->broadcast_head, |
684 | plugin->broadcast_tail, p); | 692 | plugin->broadcast_tail, p); |
685 | GNUNET_free (p->addr); | 693 | GNUNET_free (p->addr); |
686 | GNUNET_free (p); | 694 | GNUNET_free (p); |
695 | } | ||
687 | } | 696 | } |
697 | |||
698 | /* Destroy MSTs */ | ||
688 | if (NULL != plugin->broadcast_ipv4_mst) | 699 | if (NULL != plugin->broadcast_ipv4_mst) |
689 | { | 700 | { |
690 | GNUNET_SERVER_mst_destroy (plugin->broadcast_ipv4_mst); | 701 | GNUNET_SERVER_mst_destroy (plugin->broadcast_ipv4_mst); |