X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fdv%2Fplugin_transport_dv.c;h=697ca0c4cf211e3fa5cea15eaacdfc6efda51e57;hb=19377520016cc644070d207af34ae3e76618fdc8;hp=2c9881d30351526b7f05504fc06061a03875af87;hpb=9c923d1ef6752f40535124439fed299ee4150795;p=oweals%2Fgnunet.git diff --git a/src/dv/plugin_transport_dv.c b/src/dv/plugin_transport_dv.c index 2c9881d30..697ca0c4c 100644 --- a/src/dv/plugin_transport_dv.c +++ b/src/dv/plugin_transport_dv.c @@ -4,7 +4,7 @@ GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 2, or (at your + by the Free Software Foundation; either version 3, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but @@ -19,33 +19,13 @@ */ /** - * @file transport/plugin_transport_dv.c + * @file dv/plugin_transport_dv.c * @brief DV transport service, takes incoming DV requests and deals with * the DV service + * @author Nathan Evans * @author Christian Grothoff */ -/** - * TODO: - * - * As a start, the dv plugin needs to listen for information from the dv - * service. The plugin (?) will be notified by core (?) when a tcp/udp/whatever - * message comes in that should be for dv. The plugin will then hand off the message - * to the dv service which will decrypt/validate the message (?) and then send the - * result back to us (the transport) which will then send the message to the transport - * service (yikes). - * - * Or, core will notify the dv service directly which will validate, - * etc. and then just send a message to us. - * - * For starters, this plugin needs to have a client which will listen for messages from - * the dv service that need to be sent up to the gnunet-transport-service. - * - * Messages sent from the dv transport get passed to the dv service which deals - * with the actual sending (how much state does this transport need? should it know - * which peers it is currently connected to and their distances, or just assume that - * anything should be passed along to the dv service?). - */ #include "platform.h" #include "gnunet_protocols.h" #include "gnunet_connection_lib.h" @@ -54,7 +34,7 @@ #include "gnunet_statistics_service.h" #include "gnunet_dv_service.h" #include "gnunet_transport_service.h" -#include "../transport/plugin_transport.h" +#include "gnunet_transport_plugin.h" #include "dv.h" #define DEBUG_TEMPLATE GNUNET_NO @@ -138,11 +118,6 @@ struct Plugin */ struct Session *sessions; - /** - * Handle for the statistics service. - */ - struct GNUNET_STATISTICS_Handle *statistics; - /** * Our server. */ @@ -166,20 +141,39 @@ struct Plugin }; - +/** + * Handler for messages received from the DV service. + */ void handle_dv_message_received (void *cls, struct GNUNET_PeerIdentity *sender, - struct GNUNET_MessageHeader *msg, - unsigned int distance, + char *msg, + size_t msg_len, + uint32_t distance, char *sender_address, size_t sender_address_len) { struct Plugin *plugin = cls; - - plugin->env->receive(plugin, +#if DEBUG_DV_MESSAGES + char *my_id; + my_id = GNUNET_strdup(GNUNET_i2s(plugin->env->my_identity)); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, + "plugin_transport_dv", + _("%s Received message from %s of type %d, distance %u!\n"), + my_id, GNUNET_i2s(sender), ntohs(((struct GNUNET_MessageHeader *)msg)->type), distance); + GNUNET_free_non_null(my_id); +#endif + struct GNUNET_TRANSPORT_ATS_Information ats[2]; + ats[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE); + ats[0].value = htonl (distance); + ats[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); + ats[1].value = htonl (0); + + plugin->env->receive(plugin->env->cls, sender, - msg, - distance, + (struct GNUNET_MessageHeader *)msg, + (const struct GNUNET_TRANSPORT_ATS_Information *) &ats, + 2, + NULL, sender_address, sender_address_len); @@ -201,6 +195,7 @@ void handle_dv_message_received (void *cls, * @param msgbuf the message to transmit * @param msgbuf_size number of bytes in 'msgbuf' * @param timeout when should we time out + * @param session the session used * @param addr the address to use (can be NULL if the plugin * is "on its own" (i.e. re-use existing TCP connection)) * @param addrlen length of the address in bytes @@ -223,6 +218,7 @@ dv_plugin_send (void *cls, size_t msgbuf_size, unsigned int priority, struct GNUNET_TIME_Relative timeout, + struct Session *session, const void *addr, size_t addrlen, int force_address, @@ -232,9 +228,6 @@ dv_plugin_send (void *cls, int ret = 0; struct Plugin *plugin = cls; - /* FIXME: do we want the dv plugin to remember sent messages to call continuation once message actually goes out? - * Or do we just call the continuation once we've notified the plugin? - */ ret = GNUNET_DV_send(plugin->dv_handle, target, msgbuf, @@ -242,14 +235,9 @@ dv_plugin_send (void *cls, priority, timeout, addr, - addrlen); - /*, cont, cont_cls);*/ - - if (ret == 0) - cont(cls, target, GNUNET_OK); - else - cont(cls, target, GNUNET_SYSERR); - + addrlen, + cont, + cont_cls); return ret; } @@ -265,7 +253,7 @@ dv_plugin_send (void *cls, */ static void dv_plugin_disconnect (void *cls, - const struct GNUNET_PeerIdentity *target) + const struct GNUNET_PeerIdentity *target) { // struct Plugin *plugin = cls; // TODO: Add message type to send to dv service to "disconnect" a peer @@ -296,34 +284,102 @@ dv_plugin_address_pretty_printer (void *cls, GNUNET_TRANSPORT_AddressStringCallback asc, void *asc_cls) { - asc (asc_cls, NULL); + char *dest_peer; + char *via_peer; + char *print_string; + char *addr_buf = (char *)addr; + + if (addrlen != sizeof(struct GNUNET_PeerIdentity) * 2) + { + asc (asc_cls, NULL); + } + else + { + dest_peer = GNUNET_strdup(GNUNET_i2s((struct GNUNET_PeerIdentity *)addr)); + via_peer = GNUNET_strdup(GNUNET_i2s((struct GNUNET_PeerIdentity *)&addr_buf[sizeof(struct GNUNET_PeerIdentity)])); + GNUNET_asprintf(&print_string, "DV Peer `%s' via peer`%s'", dest_peer, via_peer); + asc (asc_cls, print_string); + asc (asc_cls, NULL); + GNUNET_free(via_peer); + GNUNET_free(dest_peer); + GNUNET_free(print_string); + } } +/** + * Convert the DV address to a pretty string. + * + * @param cls closure + * @param addr the (hopefully) DV address + * @param addrlen the length of the address + * + * @return string representing the DV address + */ +static const char *address_to_string (void *cls, + const void *addr, + size_t addrlen) +{ + static char return_buffer[2 * 4 + 2]; // Two four character peer identity prefixes a ':' and '\0' + + struct GNUNET_CRYPTO_HashAsciiEncoded peer_hash; + struct GNUNET_CRYPTO_HashAsciiEncoded via_hash; + struct GNUNET_PeerIdentity *peer; + struct GNUNET_PeerIdentity *via; + char *addr_buf = (char *)addr; + + if (addrlen == (2 * sizeof(struct GNUNET_PeerIdentity))) + { + peer = (struct GNUNET_PeerIdentity *)addr_buf; + via = (struct GNUNET_PeerIdentity *)&addr_buf[sizeof(struct GNUNET_PeerIdentity)]; + + GNUNET_CRYPTO_hash_to_enc (&peer->hashPubKey, &peer_hash); + peer_hash.encoding[4] = '\0'; + GNUNET_CRYPTO_hash_to_enc (&via->hashPubKey, &via_hash); + via_hash.encoding[4] = '\0'; + GNUNET_snprintf (return_buffer, + sizeof (return_buffer), + "%s:%s", + &peer_hash, + &via_hash); + } + else + return NULL; + return return_buffer; +} /** - * Another peer has suggested an address for this - * peer and transport plugin. Check that this could be a valid - * address. If so, consider adding it to the list - * of addresses. + * Another peer has suggested an address for this peer and transport + * plugin. Check that this could be a valid address. This function + * is not expected to 'validate' the address in the sense of trying to + * connect to it but simply to see if the binary format is technically + * legal for establishing a connection to this peer (and make sure that + * the address really corresponds to our network connection/settings + * and not some potential man-in-the-middle). * * @param cls closure * @param addr pointer to the address * @param addrlen length of addr * @return GNUNET_OK if this is a plausible address for this peer - * and transport + * and transport, GNUNET_SYSERR if not * - * FIXME: does this mean anything for the DV plugin? */ static int -dv_plugin_address_suggested (void *cls, - void *addr, size_t addrlen) +dv_plugin_check_address (void *cls, + const void *addr, size_t addrlen) { - /* struct Plugin *plugin = cls; */ - - /* check if the address is plausible; if so, - add it to our list! */ - return GNUNET_NO; + struct Plugin *plugin = cls; + /* Verify that the first peer of this address matches our peer id! */ + if ((addrlen != (2 * sizeof(struct GNUNET_PeerIdentity))) || (0 != memcmp(addr, plugin->env->my_identity, sizeof(struct GNUNET_PeerIdentity)))) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: Address not correct size or identity doesn't match ours!\n", GNUNET_i2s(plugin->env->my_identity)); + if (addrlen == (2 * sizeof(struct GNUNET_PeerIdentity))) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Peer in address is %s\n", GNUNET_i2s(addr)); + } + return GNUNET_SYSERR; + } + return GNUNET_OK; } @@ -336,52 +392,11 @@ libgnunet_plugin_transport_dv_init (void *cls) struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; struct GNUNET_TRANSPORT_PluginFunctions *api; struct Plugin *plugin; - struct GNUNET_SERVICE_Context *service; - - /** - * Do we not even need a service for this thing? That's peculiar. - */ - /* - service = GNUNET_SERVICE_start ("transport-dv", env->sched, env->cfg); - if (service == NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, - "dv", - _ - ("Failed to start service for `%s' transport plugin.\n"), - "dv"); - return NULL; - } - */ - /** - * I don't think we need a port, the only way we get stuff is being directly - * called by service transport or by responses from the dv-service via our - * client handle - */ - /* - if ((GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (env->cfg, - "transport-dv", - "PORT", - &port))) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - "dv", - _ - ("Require valid port number for service `%s' in configuration!\n"), - "transport-dv"); - GNUNET_SERVICE_stop (service); - return NULL; - } - */ plugin = GNUNET_malloc (sizeof (struct Plugin)); plugin->env = env; - plugin->statistics = NULL; - //plugin->service = service; - //plugin->server = GNUNET_SERVICE_get_server (service); - plugin->dv_handle = GNUNET_DV_connect(env->sched, env->cfg, &handle_dv_message_received, plugin); + plugin->dv_handle = GNUNET_DV_connect(env->cfg, &handle_dv_message_received, plugin); if (plugin->dv_handle == NULL) { @@ -394,7 +409,8 @@ libgnunet_plugin_transport_dv_init (void *cls) api->send = &dv_plugin_send; api->disconnect = &dv_plugin_disconnect; api->address_pretty_printer = &dv_plugin_address_pretty_printer; - api->check_address = &dv_plugin_address_suggested; + api->check_address = &dv_plugin_check_address; + api->address_to_string = &address_to_string; return api; } @@ -408,6 +424,9 @@ libgnunet_plugin_transport_dv_done (void *cls) struct GNUNET_TRANSPORT_PluginFunctions *api = cls; struct Plugin *plugin = api->cls; + if (plugin->dv_handle != NULL) + GNUNET_DV_disconnect(plugin->dv_handle); + GNUNET_free (plugin); GNUNET_free (api); return NULL;