From: Matthias Wachs Date: Mon, 30 Jan 2012 11:02:54 +0000 (+0000) Subject: - changes X-Git-Tag: initial-import-from-subversion-38251~15008 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=950c22927b978fde5cfd92d9b1ff7a6523dcb569;p=oweals%2Fgnunet.git - changes --- diff --git a/src/transport/plugin_transport_udp_new.c b/src/transport/plugin_transport_udp_new.c index 5844a68bb..fb8c6cf36 100644 --- a/src/transport/plugin_transport_udp_new.c +++ b/src/transport/plugin_transport_udp_new.c @@ -413,6 +413,114 @@ udp_nat_port_map_callback (void *cls, int add_remove, } +/** + * Read and process a message from the given socket. + * + * @param plugin the overall plugin + * @param rsock socket to read from + */ +static void +udp_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) +{ + socklen_t fromlen; + char addr[32]; + char buf[65536]; + ssize_t size; + const struct GNUNET_MessageHeader *msg; + //const struct GNUNET_MessageHeader *ack; + //struct Session *peer_session; + //const struct UDP_ACK_Message *udp_ack; + //struct ReceiveContext *rc; + //struct GNUNET_TIME_Absolute now; + //struct FindReceiveContext frc; + //struct Session *s = NULL; + //struct GNUNET_TIME_Relative flow_delay; + //struct GNUNET_ATS_Information ats; + + fromlen = sizeof (addr); + memset (&addr, 0, sizeof (addr)); + size = GNUNET_NETWORK_socket_recvfrom (rsock, buf, sizeof (buf), + (struct sockaddr *) &addr, &fromlen); + if (size < sizeof (struct GNUNET_MessageHeader)) + { + GNUNET_break_op (0); + return; + } + msg = (const struct GNUNET_MessageHeader *) buf; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "UDP received %u-byte message from `%s' type %i\n", (unsigned int) size, + GNUNET_a2s ((const struct sockaddr *) addr, fromlen), ntohs (msg->type)); + + if (size != ntohs (msg->size)) + { + GNUNET_break_op (0); + return; + } + switch (ntohs (msg->type)) + { + case GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON: + { + udp_broadcast_receive(plugin, &buf, size, addr, fromlen); + return; + } + case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE: + if (ntohs (msg->size) < sizeof (struct UDPMessage)) + { + GNUNET_break_op (0); + return; + } + /* + process_udp_message (plugin, (const struct UDPMessage *) msg, + (const struct sockaddr *) addr, fromlen); + */ + return; + default: + GNUNET_break_op (0); + return; + } +} + +/** + * We have been notified that our readset has something to read. We don't + * know which socket needs to be read, so we have to check each one + * Then reschedule this function to be called again once more is available. + * + * @param cls the plugin handle + * @param tc the scheduling context (for rescheduling this function again) + */ +static void +udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Plugin *plugin = cls; + + plugin->select_task = GNUNET_SCHEDULER_NO_TASK; + if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) + return; + + if ((tc->reason & GNUNET_SCHEDULER_REASON_READ_READY) != 0) + { + if ((NULL != plugin->sockv4) && + (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv4))) + udp_read (plugin, plugin->sockv4); + if ((NULL != plugin->sockv6) && + (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv6))) + udp_read (plugin, plugin->sockv6); + } + + if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0) + { + /* TODO */ + } + + plugin->select_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, + GNUNET_SCHEDULER_NO_TASK, + GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs, + plugin->ws, &udp_plugin_select, plugin); + +} + + static int setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct sockaddr_in *serverAddrv4) { @@ -525,15 +633,29 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct /* Create file descriptors */ plugin->rs = GNUNET_NETWORK_fdset_create (); + plugin->ws = GNUNET_NETWORK_fdset_create (); GNUNET_NETWORK_fdset_zero (plugin->rs); + GNUNET_NETWORK_fdset_zero (plugin->ws); if (NULL != plugin->sockv4) + { GNUNET_NETWORK_fdset_set (plugin->rs, plugin->sockv4); + GNUNET_NETWORK_fdset_set (plugin->ws, plugin->sockv4); + } if (NULL != plugin->sockv6) + { GNUNET_NETWORK_fdset_set (plugin->rs, plugin->sockv6); + GNUNET_NETWORK_fdset_set (plugin->ws, plugin->sockv6); + } if (sockets_created == 0) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to open UDP sockets\n")); + plugin->select_task = + GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, + GNUNET_SCHEDULER_NO_TASK, + GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs, + plugin->ws, &udp_plugin_select, plugin); + plugin->nat = GNUNET_NAT_register (plugin->env->cfg, GNUNET_NO, plugin->port, sockets_created, @@ -687,8 +809,9 @@ libgnunet_plugin_transport_udp_init (void *cls) GNUNET_free (api); return NULL; } + LOG (GNUNET_ERROR_TYPE_ERROR, "Starting broadcasting\n"); - //setup_broadcast (plugin, &serverAddrv6, &serverAddrv4); + setup_broadcast (plugin, &serverAddrv6, &serverAddrv4); GNUNET_free_non_null (bind4_address); @@ -710,6 +833,8 @@ libgnunet_plugin_transport_udp_done (void *cls) struct GNUNET_TRANSPORT_PluginFunctions *api = cls; struct Plugin *plugin = api->cls; + stop_broadcast (plugin); + /* Closing sockets */ if (plugin->sockv4 != NULL) { @@ -722,6 +847,7 @@ libgnunet_plugin_transport_udp_done (void *cls) plugin->sockv6 = NULL; } GNUNET_NETWORK_fdset_destroy (plugin->rs); + GNUNET_NETWORK_fdset_destroy (plugin->ws); GNUNET_NAT_unregister (plugin->nat); plugin->nat = NULL; diff --git a/src/transport/plugin_transport_udp_new.h b/src/transport/plugin_transport_udp_new.h index b71a0d499..c98553062 100644 --- a/src/transport/plugin_transport_udp_new.h +++ b/src/transport/plugin_transport_udp_new.h @@ -87,6 +87,28 @@ struct IPv6UdpAddress GNUNET_NETWORK_STRUCT_END +/** + * UDP Message-Packet header (after defragmentation). + */ +struct UDPMessage +{ + /** + * Message header. + */ + struct GNUNET_MessageHeader header; + + /** + * Always zero for now. + */ + uint32_t reserved; + + /** + * What is the identity of the sender + */ + struct GNUNET_PeerIdentity sender; + +}; + /** * Encapsulation of all of the state of the plugin. @@ -151,6 +173,11 @@ struct Plugin */ struct GNUNET_NETWORK_FDSet *rs; + /** + * FD Write set + */ + struct GNUNET_NETWORK_FDSet *ws; + /** * The read socket for IPv4 */ @@ -241,7 +268,13 @@ struct Plugin const char * udp_address_to_string (void *cls, const void *addr, size_t addrlen); +void +udp_broadcast_receive (); + void setup_broadcast (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct sockaddr_in *serverAddrv4); +void +stop_broadcast (struct Plugin *plugin); + /* end of plugin_transport_udp.h */ diff --git a/src/transport/plugin_transport_udp_new_broadcasting.c b/src/transport/plugin_transport_udp_new_broadcasting.c index 7513cb626..849cdd15f 100644 --- a/src/transport/plugin_transport_udp_new_broadcasting.c +++ b/src/transport/plugin_transport_udp_new_broadcasting.c @@ -173,6 +173,54 @@ broadcast_ipv4_mst_cb (void *cls, void *client, GNUNET_free (mc); } +void +udp_broadcast_receive (struct Plugin *plugin, const char * buf, ssize_t size, struct sockaddr *addr, size_t addrlen) +{ + struct GNUNET_ATS_Information ats; + + if (addrlen == sizeof (struct sockaddr_in)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received IPv4 HELLO beacon broadcast with %i bytes from address %s\n", + size, GNUNET_a2s ((const struct sockaddr *) addr, addrlen)); + + struct Mstv4Context *mc; + + mc = GNUNET_malloc (sizeof (struct Mstv4Context)); + struct sockaddr_in *av4 = (struct sockaddr_in *) addr; + + mc->addr.ipv4_addr = av4->sin_addr.s_addr; + mc->addr.u4_port = av4->sin_port; + ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) addr, addrlen); + mc->ats_address_network_type = ats.value; + if (GNUNET_OK != + GNUNET_SERVER_mst_receive (plugin->broadcast_ipv4_mst, mc, buf, size, + GNUNET_NO, GNUNET_NO)) + GNUNET_free (mc); + } + else if (addrlen == sizeof (struct sockaddr_in6)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received IPv6 HELLO beacon broadcast with %i bytes from address %s\n", + size, GNUNET_a2s ((const struct sockaddr *) &addr, addrlen)); + + struct Mstv6Context *mc; + + mc = GNUNET_malloc (sizeof (struct Mstv6Context)); + struct sockaddr_in6 *av6 = (struct sockaddr_in6 *) addr; + + mc->addr.ipv6_addr = av6->sin6_addr; + mc->addr.u6_port = av6->sin6_port; + ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) addr, addrlen); + mc->ats_address_network_type = ats.value; + + if (GNUNET_OK != + GNUNET_SERVER_mst_receive (plugin->broadcast_ipv6_mst, mc, buf, size, + GNUNET_NO, GNUNET_NO)) + GNUNET_free (mc); + } +} + static void udp_ipv4_broadcast_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)