X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fdv%2Fplugin_transport_dv.c;h=5e2a6bd6c072ee677f9b760d3a156241fdebb070;hb=735eef3c649f45c9c38622f126c2347f7174a19d;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..5e2a6bd6c 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,10 +34,10 @@ #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 +#define DEBUG_TEMPLATE GNUNET_EXTRA_LOGGING /** * Encapsulation of all of the state of the plugin. @@ -138,11 +118,6 @@ struct Plugin */ struct Session *sessions; - /** - * Handle for the statistics service. - */ - struct GNUNET_STATISTICS_Handle *statistics; - /** * Our server. */ @@ -166,22 +141,38 @@ struct Plugin }; - -void handle_dv_message_received (void *cls, - struct GNUNET_PeerIdentity *sender, - struct GNUNET_MessageHeader *msg, - unsigned int distance, - char *sender_address, - size_t sender_address_len) +/** + * Handler for messages received from the DV service. + */ +void +handle_dv_message_received (void *cls, struct GNUNET_PeerIdentity *sender, + 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, - sender, - msg, - distance, - sender_address, - sender_address_len); +#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_ATS_Information ats[2]; + + ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); + ats[0].value = htonl (distance); + ats[1].type = htonl (GNUNET_ATS_ARRAY_TERMINATOR); + ats[1].value = htonl (0); + + plugin->env->receive (plugin->env->cls, sender, + (struct GNUNET_MessageHeader *) msg, + (const struct GNUNET_ATS_Information *) &ats, + 2, NULL, sender_address, sender_address_len); } @@ -201,6 +192,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 @@ -217,39 +209,18 @@ void handle_dv_message_received (void *cls, * and does NOT mean that the message was not transmitted (DV) */ static ssize_t -dv_plugin_send (void *cls, - const struct GNUNET_PeerIdentity *target, - const char *msgbuf, - size_t msgbuf_size, - unsigned int priority, - struct GNUNET_TIME_Relative timeout, - const void *addr, - size_t addrlen, - int force_address, - GNUNET_TRANSPORT_TransmitContinuation - cont, void *cont_cls) +dv_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target, + const char *msgbuf, size_t msgbuf_size, unsigned int priority, + struct GNUNET_TIME_Relative timeout, struct Session *session, + const void *addr, size_t addrlen, int force_address, + GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_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, - msgbuf_size, - priority, - timeout, - addr, - addrlen); - /*, cont, cont_cls);*/ - - if (ret == 0) - cont(cls, target, GNUNET_OK); - else - cont(cls, target, GNUNET_SYSERR); - + ret = + GNUNET_DV_send (plugin->dv_handle, target, msgbuf, msgbuf_size, priority, + timeout, addr, addrlen, cont, cont_cls); return ret; } @@ -264,8 +235,7 @@ dv_plugin_send (void *cls, * @param target peer from which to disconnect */ static void -dv_plugin_disconnect (void *cls, - const struct GNUNET_PeerIdentity *target) +dv_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) { // struct Plugin *plugin = cls; // TODO: Add message type to send to dv service to "disconnect" a peer @@ -287,43 +257,117 @@ dv_plugin_disconnect (void *cls, * @param asc_cls closure for asc */ static void -dv_plugin_address_pretty_printer (void *cls, - const char *type, - const void *addr, - size_t addrlen, - int numeric, +dv_plugin_address_pretty_printer (void *cls, const char *type, const void *addr, + size_t addrlen, int numeric, struct GNUNET_TIME_Relative timeout, - GNUNET_TRANSPORT_AddressStringCallback - asc, void *asc_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; */ + struct Plugin *plugin = cls; - /* check if the address is plausible; if so, - add it to our list! */ - return GNUNET_NO; + /* 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,56 +380,16 @@ 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) { - GNUNET_free(plugin); + GNUNET_free (plugin); return NULL; } @@ -394,7 +398,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 +413,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;