X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftransport%2Fgnunet-service-transport.c;h=cd9bb5c65e2018cd2f21c8d7badba5ff8ba69fae;hb=107a20218f88dcd4f41869c233d89835fb9c1ac5;hp=a39cc086720222846de76af2359069090bed1ea3;hpb=4beecb7f68aa61b61740c60716b0d6050bde41b6;p=oweals%2Fgnunet.git diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index a39cc0867..cd9bb5c65 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c @@ -19,12 +19,13 @@ */ /** - * @file transport/gnunet-service-transport-new.c + * @file transport/gnunet-service-transport.c * @brief * @author Christian Grothoff */ #include "platform.h" #include "gnunet_util_lib.h" +#include "gnunet_hello_lib.h" #include "gnunet_statistics_service.h" #include "gnunet_transport_service.h" #include "gnunet_peerinfo_service.h" @@ -83,17 +84,13 @@ struct GNUNET_ATS_SchedulingHandle *GST_ats; * @param target a connected neighbour * @param ats performance information (unused) * @param ats_count number of records in ats (unused) - * @param transport plugin - * @param addr address - * @param addrlen address length + * @param address the address */ static void transmit_our_hello (void *cls, const struct GNUNET_PeerIdentity *target, const struct GNUNET_ATS_Information *ats, uint32_t ats_count, - const char * transport, - const void * addr, - size_t addrlen) + const struct GNUNET_HELLO_Address *address) { const struct GNUNET_MessageHeader *hello = cls; @@ -118,61 +115,66 @@ process_hello_update (void *cls, const struct GNUNET_MessageHeader *hello) /** - * We received some payload. Prepare to pass it on to our clients. + * We received some payload. Prepare to pass it on to our clients. * * @param peer (claimed) identity of the other peer - * @param message the message, never NULL + * @param address the address + * @param session session used + * @param message the message to process * @param ats performance information * @param ats_count number of records in ats * @return how long the plugin should wait until receiving more data */ static struct GNUNET_TIME_Relative process_payload (const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_MessageHeader *message, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_MessageHeader *message, + const struct GNUNET_ATS_Information *ats, uint32_t ats_count) { struct GNUNET_TIME_Relative ret; int do_forward; struct InboundMessage *im; size_t msg_size = ntohs (message->size); - size_t size = sizeof (struct InboundMessage) + msg_size + sizeof (struct GNUNET_ATS_Information) * ats_count; + size_t size = + sizeof (struct InboundMessage) + msg_size + + sizeof (struct GNUNET_ATS_Information) * (ats_count + 1); char buf[size]; struct GNUNET_ATS_Information *ap; - + ret = GNUNET_TIME_UNIT_ZERO; do_forward = GNUNET_SYSERR; - ret = - GST_neighbours_calculate_receive_delay (peer, - msg_size, - &do_forward); + ret = GST_neighbours_calculate_receive_delay (peer, msg_size, &do_forward); if (!GST_neighbours_test_connected (peer)) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Discarded %u bytes type %u payload from peer `%s'\n", - msg_size, - ntohs (message->type), - GNUNET_i2s (peer)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Discarded %u bytes type %u payload from peer `%s'\n", msg_size, + ntohs (message->type), GNUNET_i2s (peer)); GNUNET_STATISTICS_update (GST_stats, - gettext_noop ("# bytes payload discarded due to not connected peer "), - msg_size, - GNUNET_NO); + gettext_noop + ("# bytes payload discarded due to not connected peer "), + msg_size, GNUNET_NO); return ret; } if (do_forward != GNUNET_YES) return ret; - im = (struct InboundMessage*) buf; + im = (struct InboundMessage *) buf; im->header.size = htons (size); im->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RECV); - im->ats_count = htonl (ats_count); + im->ats_count = htonl (ats_count + 1); im->peer = *peer; - ap = (struct GNUNET_ATS_Information*) &im[1]; + ap = (struct GNUNET_ATS_Information *) &im[1]; memcpy (ap, ats, ats_count * sizeof (struct GNUNET_ATS_Information)); - memcpy (&ap[ats_count], message, ntohs (message->size)); + ap[ats_count].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); + ap[ats_count].value = + htonl ((uint32_t) GST_neighbour_get_latency (peer).rel_value); + memcpy (&ap[ats_count + 1], message, ntohs (message->size)); + GNUNET_ATS_address_update (GST_ats, address, session, ap, ats_count + 1); GST_clients_broadcast (&im->header, GNUNET_YES); return ret; @@ -212,15 +214,20 @@ plugin_env_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer, { const char *plugin_name = cls; struct GNUNET_TIME_Relative ret; + struct GNUNET_HELLO_Address address; uint16_t type; - + + address.peer = *peer; + address.address = sender_address; + address.address_length = sender_address_len; + address.transport_name = plugin_name; ret = GNUNET_TIME_UNIT_ZERO; if (NULL == message) goto end; type = ntohs (message->type); #if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received Message with type %u\n", type); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Message with type %u\n", type); #endif switch (type) @@ -231,43 +238,32 @@ plugin_env_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer, case GNUNET_MESSAGE_TYPE_TRANSPORT_PING: #if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, - "Processing `%s' from `%s'\n", "PING", - (sender_address != NULL) ? GST_plugins_a2s (plugin_name, - sender_address, - sender_address_len) - : ""); + "Processing `%s' from `%s'\n", "PING", + (sender_address != + NULL) ? GST_plugins_a2s (&address) : ""); #endif - GST_validation_handle_ping (peer, message, plugin_name, session, - sender_address, sender_address_len); + GST_validation_handle_ping (peer, message, &address, session); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG: #if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, - "Processing `%s' from `%s'\n", "PONG", - (sender_address != NULL) ? GST_plugins_a2s (plugin_name, - sender_address, - sender_address_len) - : ""); + "Processing `%s' from `%s'\n", "PONG", + (sender_address != + NULL) ? GST_plugins_a2s (&address) : ""); #endif GST_validation_handle_pong (peer, message); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT: - GST_neighbours_handle_connect (message, - peer, - plugin_name, sender_address, sender_address_len, - session, ats, ats_count); + GST_neighbours_handle_connect (message, peer, &address, session, ats, + ats_count); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT_ACK: - GST_neighbours_handle_connect_ack (message, - peer, - plugin_name, sender_address, sender_address_len, - session, ats, ats_count); + GST_neighbours_handle_connect_ack (message, peer, &address, session, ats, + ats_count); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK: - GST_neighbours_handle_ack (message, - peer, - plugin_name, sender_address, sender_address_len, - session, ats, ats_count); + GST_neighbours_handle_ack (message, peer, &address, session, ats, + ats_count); break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT: GST_neighbours_handle_disconnect_message (peer, message); @@ -275,27 +271,24 @@ plugin_env_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer, case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE: GST_neighbours_keepalive (peer); break; + case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE: + GST_neighbours_keepalive_response (peer, ats, ats_count); + break; default: /* should be payload */ - ret = process_payload (peer, - message, - ats, ats_count); + ret = process_payload (peer, &address, session, message, ats, ats_count); break; } - end: +end: #if 1 /* FIXME: this should not be needed, and not sure it's good to have it, but without - this connections seem to go extra-slow */ - GNUNET_ATS_address_update (GST_ats, peer, - plugin_name, sender_address, sender_address_len, - session, - ats, ats_count); + * this connections seem to go extra-slow */ + GNUNET_ATS_address_update (GST_ats, &address, session, ats, ats_count); #endif #if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Allowing receive from peer %s to continue in %llu ms\n", - GNUNET_i2s (peer), - (unsigned long long) ret.rel_value); + "Allowing receive from peer %s to continue in %llu ms\n", + GNUNET_i2s (peer), (unsigned long long) ret.rel_value); #endif return ret; } @@ -317,8 +310,13 @@ plugin_env_address_change_notification (void *cls, int add_remove, const void *addr, size_t addrlen) { const char *plugin_name = cls; + struct GNUNET_HELLO_Address address; - GST_hello_modify_addresses (add_remove, plugin_name, addr, addrlen); + address.peer = GST_my_identity; + address.transport_name = plugin_name; + address.address = addr; + address.address_length = addrlen; + GST_hello_modify_addresses (add_remove, &address); } @@ -339,19 +337,61 @@ static void plugin_env_session_end (void *cls, const struct GNUNET_PeerIdentity *peer, struct Session *session) { + const char *transport_name = cls; + struct GNUNET_HELLO_Address address; + + GNUNET_assert (strlen (transport_name) > 0); #if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Session %X to peer `%s' ended \n", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %X to peer `%s' ended \n", session, GNUNET_i2s (peer)); #endif if (NULL != session) - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK, - "transport-ats", - "Telling ATS to destroy session %p from peer %s\n", - session, - GNUNET_i2s (peer)); - GNUNET_ATS_address_destroyed (GST_ats, peer, NULL, NULL, 0, session); + GNUNET_log_from (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK, + "transport-ats", + "Telling ATS to destroy session %p from peer %s\n", + session, GNUNET_i2s (peer)); + address.peer = *peer; + address.address = NULL; + address.address_length = 0; + address.transport_name = transport_name; GST_neighbours_session_terminated (peer, session); + GNUNET_ATS_address_destroyed (GST_ats, &address, session); +} + + +/** + * Function that will be called to figure if an address is an loopback, + * LAN, WAN etc. address + * + * @param cls closure + * @param addr binary address + * @param addrlen length of the address + * @return ATS Information containing the network type + */ +static const struct GNUNET_ATS_Information +plugin_env_address_to_type (void *cls, + const struct sockaddr *addr, + size_t addrlen) +{ + struct GNUNET_ATS_Information ats; + ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); + ats.value = htonl (GNUNET_ATS_NET_UNSPECIFIED); + if (GST_ats == NULL) + { + GNUNET_break (0); + return ats; + } + if (((addr->sa_family != AF_INET) && (addrlen != sizeof (struct sockaddr_in))) && + ((addr->sa_family != AF_INET6) && (addrlen != sizeof (struct sockaddr_in6))) && + (addr->sa_family != AF_UNIX)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed address with length %u `%s'\n", + addrlen, + GNUNET_a2s(addr, addrlen)); + GNUNET_break (0); + return (const struct GNUNET_ATS_Information) ats; + } + return GNUNET_ATS_address_get_type(GST_ats, addr, addrlen); } @@ -363,42 +403,40 @@ plugin_env_session_end (void *cls, const struct GNUNET_PeerIdentity *peer, * actually happened. * * @param cls closure - * @param peer identity of the peer - * @param plugin_name name of the transport plugin, NULL to disconnect + * @param address address to use (for peer given in address) * @param session session to use (if available) - * @param plugin_addr address to use (if available) - * @param plugin_addr_len number of bytes in addr * @param bandwidth_out assigned outbound bandwidth for the connection, 0 to disconnect from peer * @param bandwidth_in assigned inbound bandwidth for the connection, 0 to disconnect from peer + * @param ats ATS information + * @param ats_count number of ATS elements */ static void -ats_request_address_change (void *cls, const struct GNUNET_PeerIdentity *peer, - const char *plugin_name, - const void *plugin_addr, size_t plugin_addr_len, +ats_request_address_change (void *cls, + const struct GNUNET_HELLO_Address *address, struct Session *session, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, - const struct GNUNET_ATS_Information * ats, + const struct GNUNET_ATS_Information *ats, uint32_t ats_count) { uint32_t bw_in = ntohl (bandwidth_in.value__); uint32_t bw_out = ntohl (bandwidth_out.value__); - /* ATS tells me to disconnect from peer*/ + /* ATS tells me to disconnect from peer */ if ((bw_in == 0) && (bw_out == 0)) { #if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "ATS tells me to disconnect from peer `%s'\n", - GNUNET_i2s (peer)); + "ATS tells me to disconnect from peer `%s'\n", + GNUNET_i2s (&address->peer)); #endif - GST_neighbours_force_disconnect(peer); + GST_neighbours_force_disconnect (&address->peer); return; } /* will never return GNUNET_YES since connection is to be established */ - GST_neighbours_switch_to_address_3way (peer, plugin_name, plugin_addr, - plugin_addr_len, session, ats, ats_count, - bandwidth_in, bandwidth_out); + GST_neighbours_switch_to_address (&address->peer, address, session, ats, + ats_count, bandwidth_in, + bandwidth_out); } @@ -414,10 +452,11 @@ ats_request_address_change (void *cls, const struct GNUNET_PeerIdentity *peer, static void neighbours_connect_notification (void *cls, const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_ATS_Information - *ats, uint32_t ats_count) + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count) { - size_t len = sizeof (struct ConnectInfoMessage) + + size_t len = + sizeof (struct ConnectInfoMessage) + ats_count * sizeof (struct GNUNET_ATS_Information); char buf[len]; struct ConnectInfoMessage *connect_msg = (struct ConnectInfoMessage *) buf; @@ -428,8 +467,7 @@ neighbours_connect_notification (void *cls, connect_msg->ats_count = htonl (ats_count); connect_msg->id = *peer; ap = (struct GNUNET_ATS_Information *) &connect_msg[1]; - memcpy (ap, ats, - ats_count * sizeof (struct GNUNET_ATS_Information)); + memcpy (ap, ats, ats_count * sizeof (struct GNUNET_ATS_Information)); GST_clients_broadcast (&connect_msg->header, GNUNET_NO); } @@ -455,6 +493,23 @@ neighbours_disconnect_notification (void *cls, } +/** + * Function called to notify transport users that a neighbour peer changed its + * active address. + * + * @param cls closure + * @param peer peer this update is about (never NULL) + * @param address address, NULL on disconnect + */ +static void +neighbours_address_notification (void *cls, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Address *address) +{ + GST_clients_broadcast_address_notification (peer, address); +} + + /** * Function called when the service shuts down. Unloads our plugins * and cancels pending validations. @@ -465,9 +520,10 @@ neighbours_disconnect_notification (void *cls, static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { + GST_neighbours_stop (); GST_validation_stop (); GST_plugins_unload (); - GST_neighbours_stop (); + GNUNET_ATS_scheduling_done (GST_ats); GST_ats = NULL; GST_clients_stop (); @@ -544,12 +600,16 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, /* start subsystems */ GST_hello_start (&process_hello_update, NULL); GST_blacklist_start (server); + GST_ats = + GNUNET_ATS_scheduling_init (GST_cfg, &ats_request_address_change, NULL); GST_plugins_load (&plugin_env_receive_callback, &plugin_env_address_change_notification, - &plugin_env_session_end); - GST_ats = GNUNET_ATS_scheduling_init (GST_cfg, &ats_request_address_change, NULL); - GST_neighbours_start (NULL, &neighbours_connect_notification, - &neighbours_disconnect_notification); + &plugin_env_session_end, + &plugin_env_address_to_type); + GST_neighbours_start (NULL, + &neighbours_connect_notification, + &neighbours_disconnect_notification, + &neighbours_address_notification); GST_clients_start (server); GST_validation_start (); }