static void udp_ipv4_broadcast_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct Plugin *plugin = cls; int sent; uint16_t msg_size; char buf[65536] GNUNET_ALIGN; struct BroadcastAddress *baddr; plugin->send_ipv4_broadcast_task = GNUNET_SCHEDULER_NO_TASK; msg_size = prepare_beacon(plugin, (struct UDP_Beacon_Message *) &buf); sent = 0; baddr = plugin->ipv4_broadcast_head; /* just IPv4 */ while ((msg_size > 0) && (baddr != NULL) && (baddr->addrlen == sizeof (struct sockaddr_in))) { struct sockaddr_in *addr = (struct sockaddr_in *) baddr->addr; addr->sin_port = htons (plugin->port); sent = GNUNET_NETWORK_socket_sendto (plugin->sockv4, &buf, msg_size, (const struct sockaddr *) addr, baddr->addrlen); if (sent == GNUNET_SYSERR) { if ((ENETUNREACH == errno) || (ENETDOWN == errno)) { /* "Network unreachable" or "Network down" * * This indicates that we just do not have network connectivity */ GNUNET_log (GNUNET_ERROR_TYPE_BULK | GNUNET_ERROR_TYPE_WARNING, "Network connectivity is down, cannot send beacon!\n"); } else GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); } else { LOG (GNUNET_ERROR_TYPE_DEBUG, "Sent HELLO beacon broadcast with %i bytes to address %s\n", sent, GNUNET_a2s (baddr->addr, baddr->addrlen)); } baddr = baddr->next; } plugin->send_ipv4_broadcast_task = GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval, &udp_ipv4_broadcast_send, plugin); }
static void udp_ipv6_broadcast_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct Plugin *plugin = cls; int sent; uint16_t msg_size; char buf[65536] GNUNET_ALIGN; plugin->send_ipv6_broadcast_task = GNUNET_SCHEDULER_NO_TASK; msg_size = prepare_beacon(plugin, (struct UDP_Beacon_Message *) &buf); sent = 0; sent = GNUNET_NETWORK_socket_sendto (plugin->sockv6, &buf, msg_size, (const struct sockaddr *) &plugin->ipv6_multicast_address, sizeof (struct sockaddr_in6)); if (sent == GNUNET_SYSERR) { if ((ENETUNREACH == errno) || (ENETDOWN == errno)) { /* "Network unreachable" or "Network down" * * This indicates that this system is IPv6 enabled, but does not * have a valid global IPv6 address assigned */ GNUNET_log (GNUNET_ERROR_TYPE_BULK | GNUNET_ERROR_TYPE_WARNING, "Network connectivity is down, cannot send beacon!\n"); } else GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); } else { LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending IPv6 HELLO beacon broadcast with %i bytes to address %s\n", sent, GNUNET_a2s ((const struct sockaddr *) &plugin->ipv6_multicast_address, sizeof (struct sockaddr_in6))); } plugin->send_ipv6_broadcast_task = GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval, &udp_ipv6_broadcast_send, plugin); }
static void udp_ipv6_broadcast_send (void *cls) { struct BroadcastAddress *baddr = cls; struct Plugin *plugin = baddr->plugin; ssize_t sent; uint16_t msg_size; char buf[65536] GNUNET_ALIGN; const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) baddr->addr; baddr->broadcast_task = NULL; msg_size = prepare_beacon(plugin, (struct UDP_Beacon_Message *) &buf); /* Note: unclear if this actually works to limit the multicast to the specified interface as we're not (necessarily) using a link-local multicast group and the kernel suggests that the scope ID is only respected for link-local addresses; however, if the scope ID is ignored, the kernel should just multicast on ALL interfaces, which is merely slightly less efficient; in that case, we might want to revert to only doing this once, and not per interface (hard to test...) */ plugin->ipv6_multicast_address.sin6_scope_id = s6->sin6_scope_id; sent = GNUNET_NETWORK_socket_sendto (plugin->sockv6, &buf, msg_size, (const struct sockaddr *) &plugin->ipv6_multicast_address, sizeof (struct sockaddr_in6)); plugin->ipv6_multicast_address.sin6_scope_id = 0; if (sent == GNUNET_SYSERR) { if ((ENETUNREACH == errno) || (ENETDOWN == errno)) { /* "Network unreachable" or "Network down" * * This indicates that this system is IPv6 enabled, but does not * have a valid global IPv6 address assigned */ GNUNET_log (GNUNET_ERROR_TYPE_BULK | GNUNET_ERROR_TYPE_WARNING, "Network connectivity is down, cannot send beacon!\n"); } else GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); } else { LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending IPv6 HELLO beacon broadcast with %d bytes to address %s\n", (int) sent, GNUNET_a2s ((const struct sockaddr *) &plugin->ipv6_multicast_address, sizeof (struct sockaddr_in6))); } #if LINUX /* * Cryogenic */ if (NULL != baddr->cryogenic_fd) { baddr->cryogenic_times.delay_msecs = (plugin->broadcast_interval.rel_value_us/1000.0)*0.5; baddr->cryogenic_times.timeout_msecs = (plugin->broadcast_interval.rel_value_us/1000.0)*1.5; if (ioctl(baddr->cryogenic_fd->fd, PM_SET_DELAY_AND_TIMEOUT, &baddr->cryogenic_times) < 0) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "ioctl"); baddr->broadcast_task = GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval, &udp_ipv6_broadcast_send, baddr); } else GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, baddr->cryogenic_fd, &udp_ipv6_broadcast_send, baddr); } else #endif baddr->broadcast_task = GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval, &udp_ipv6_broadcast_send, baddr); }
static void udp_ipv4_broadcast_send (void *cls) { struct BroadcastAddress *baddr = cls; struct Plugin *plugin = baddr->plugin; int sent; uint16_t msg_size; char buf[65536] GNUNET_ALIGN; baddr->broadcast_task = NULL; msg_size = prepare_beacon(plugin, (struct UDP_Beacon_Message *) &buf); if (0 != msg_size) { struct sockaddr_in *addr = (struct sockaddr_in *) baddr->addr; addr->sin_port = htons (plugin->port); sent = GNUNET_NETWORK_socket_sendto (plugin->sockv4, &buf, msg_size, (const struct sockaddr *) addr, baddr->addrlen); if (sent == GNUNET_SYSERR) { if ((ENETUNREACH == errno) || (ENETDOWN == errno)) { /* "Network unreachable" or "Network down" * * This indicates that we just do not have network connectivity */ GNUNET_log (GNUNET_ERROR_TYPE_BULK | GNUNET_ERROR_TYPE_WARNING, "Network connectivity is down, cannot send beacon!\n"); } else GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); } else { LOG (GNUNET_ERROR_TYPE_DEBUG, "Sent HELLO beacon broadcast with %i bytes to address %s\n", sent, GNUNET_a2s (baddr->addr, baddr->addrlen)); } } #if LINUX /* * Cryogenic */ if (NULL != baddr->cryogenic_fd) { baddr->cryogenic_times.delay_msecs = (plugin->broadcast_interval.rel_value_us/1000.0)*0.5; baddr->cryogenic_times.timeout_msecs = (plugin->broadcast_interval.rel_value_us/1000.0)*1.5; if (ioctl(baddr->cryogenic_fd->fd, PM_SET_DELAY_AND_TIMEOUT, &baddr->cryogenic_times) < 0) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "ioctl"); baddr->broadcast_task = GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval, &udp_ipv4_broadcast_send, baddr); } else GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, baddr->cryogenic_fd, &udp_ipv4_broadcast_send, baddr); } else #endif baddr->broadcast_task = GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval, &udp_ipv4_broadcast_send, baddr); }