aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2013-12-18 08:57:03 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2013-12-18 08:57:03 +0000
commitba6439dcf325a3e6e598c034e60815f39646562b (patch)
treedf633a1005504e92bb3abfdbc7623d968e1cf844 /src
parent7f7906e96922d1f0410439ad08b3900937186ca5 (diff)
downloadgnunet-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.c24
-rw-r--r--src/transport/plugin_transport_udp.h5
-rw-r--r--src/transport/plugin_transport_udp_broadcasting.c73
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,
642void 647void
643stop_broadcast (struct Plugin *plugin) 648stop_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);