From: Christian Grothoff Date: Thu, 4 Aug 2011 09:39:19 +0000 (+0000) Subject: send message type maps to neighbours X-Git-Tag: initial-import-from-subversion-38251~17484 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=59e28af684bda5ce8f5060156c4fdf3077b90428;p=oweals%2Fgnunet.git send message type maps to neighbours --- diff --git a/src/core/Makefile.am b/src/core/Makefile.am index efe81a4bd..657b658b2 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -30,7 +30,7 @@ bin_PROGRAMS = \ gnunet_service_core_SOURCES = \ gnunet-service-core.c -gnunet_service_core_LDADD = \ +gnunet_service_core_LDADD = -lz \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c index eebb39581..e83156e59 100644 --- a/src/core/gnunet-service-core.c +++ b/src/core/gnunet-service-core.c @@ -23,14 +23,16 @@ * @brief high-level P2P messaging * @author Christian Grothoff * + * Type map implementation: + * - track type maps for neighbours (can wait) + * - only notify clients about peers with matching type maps (can wait) + * * Considerations for later: * - check that hostkey used by transport (for HELLOs) is the * same as the hostkey that we are using! - * - add code to send PINGs if we are about to time-out otherwise - * - optimize lookup (many O(n) list traversals - * could ideally be changed to O(1) hash map lookups) */ #include "platform.h" +#include #include "gnunet_constants.h" #include "gnunet_util_lib.h" #include "gnunet_hello_lib.h" @@ -749,6 +751,10 @@ static struct GNUNET_PeerIdentity my_identity; */ static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key; +/** + * Bitmap of message types this peer is able to handle. + */ +static uint32_t my_type_map[(UINT16_MAX + 1)/32]; /** * Handle to peerinfo service. @@ -1141,6 +1147,95 @@ schedule_peer_messages (struct Neighbour *n) } +/** + * Compute a type map message for this peer. + * + * @return this peers current type map message. + */ +static struct GNUNET_MessageHeader * +compute_type_map_message () +{ + char *tmp; + uLongf dlen; + struct GNUNET_MessageHeader *hdr; + +#ifdef compressBound + dlen = compressBound (sizeof(my_type_map)); +#else + dlen = sizeof(my_type_map) + (sizeof(my_type_map) / 100) + 20; + /* documentation says 100.1% oldSize + 12 bytes, but we + should be able to overshoot by more to be safe */ +#endif + hdr = GNUNET_malloc (dlen + sizeof (struct GNUNET_MessageHeader)); + hdr->size = htons ((uint16_t) dlen + sizeof (struct GNUNET_MessageHeader)); + tmp = (char*) &hdr[1]; + if ( (Z_OK != compress2 ((Bytef *) tmp, + &dlen, (const Bytef *) my_type_map, sizeof (my_type_map), 9)) || + (dlen >= sizeof(my_type_map)) ) + { + dlen = sizeof (my_type_map); + memcpy (tmp, my_type_map, sizeof (my_type_map)); + hdr->type = htons (GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP); + } + else + { + hdr->type = htons (GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP); + } + return hdr; +} + + +/** + * Send a type map message to the neighbour. + * + * @param cls the type map message + * @param key neighbour's identity + * @param value 'struct Neighbour' of the target + * @return always GNUNET_OK + */ +static int +send_type_map_to_neighbour (void *cls, + const GNUNET_HashCode *key, + void *value) +{ + struct GNUNET_MessageHeader *hdr = cls; + struct Neighbour *n = value; + struct MessageEntry *m; + uint16_t size; + + if (n == &self) + return GNUNET_OK; + size = ntohs (hdr->size); + m = GNUNET_malloc (sizeof (struct MessageEntry) + size); + memcpy (&m[1], hdr, size); + m->deadline = GNUNET_TIME_UNIT_FOREVER_ABS; + m->slack_deadline = GNUNET_TIME_UNIT_FOREVER_ABS; + m->priority = UINT_MAX; + m->sender_status = n->status; + m->size = size; + m->next = n->messages; + n->messages = m; + return GNUNET_OK; +} + + + +/** + * Send my type map to all connected peers (it got changed). + */ +static void +broadcast_my_type_map () +{ + struct GNUNET_MessageHeader *hdr; + + hdr = compute_type_map_message (); + GNUNET_CONTAINER_multihashmap_iterate (neighbours, + &send_type_map_to_neighbour, + hdr); + GNUNET_free (hdr); +} + + /** * Handle CORE_SEND_REQUEST message. */ @@ -1325,7 +1420,12 @@ handle_client_init (void *cls, c->types = (const uint16_t *) &c[1]; wtypes = (uint16_t *) &c[1]; for (i=0;itcnt;i++) - wtypes[i] = ntohs (types[i]); + { + wtypes[i] = ntohs (types[i]); + my_type_map[wtypes[i]/32] |= (1 << (wtypes[i] % 32)); + } + if (c->tcnt > 0) + broadcast_my_type_map (); c->options = ntohl (im->options); #if DEBUG_CORE_CLIENT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -1395,6 +1495,8 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) { struct Client *pos; struct Client *prev; + unsigned int i; + const uint16_t *wtypes; if (client == NULL) return; @@ -1429,6 +1531,16 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) GNUNET_CONTAINER_multihashmap_destroy (pos->requests); } GNUNET_free (pos); + + /* rebuild my_type_map */ + memset (my_type_map, 0, sizeof (my_type_map)); + for (pos = clients; NULL != pos; pos = pos->next) + { + wtypes = (const uint16_t *) &pos[1]; + for (i=0;itcnt;i++) + my_type_map[wtypes[i]/32] |= (1 << (wtypes[i] % 32)); + } + broadcast_my_type_map (); } @@ -1521,8 +1633,9 @@ handle_client_iterate_peers (void *cls, GNUNET_TIME_UNIT_FOREVER_REL); } + /** - * Handle CORE_ITERATE_PEERS request. Notify client about existing neighbours. + * Handle CORE_PEER_CONNECTED request. Notify client about existing neighbours. * * @param cls unused * @param client client sending the iteration request @@ -3618,6 +3731,13 @@ handle_pong (struct Neighbour *n, 1, GNUNET_NO); n->status = PEER_STATE_KEY_CONFIRMED; + { + struct GNUNET_MessageHeader *hdr; + + hdr = compute_type_map_message (); + send_type_map_to_neighbour (hdr, &n->peer.hashPubKey, n); + GNUNET_free (hdr); + } if (n->bw_out_external_limit.value__ != t.inbound_bw_limit.value__) { n->bw_out_external_limit = t.inbound_bw_limit; @@ -3956,6 +4076,12 @@ deliver_message (void *cls, buf, msize, GNUNET_NO); + if ( (GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP == type) || + (GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP == type) ) + { + /* FIXME: update message type map for 'Neighbour' */ + return; + } dropped = GNUNET_YES; cpos = clients; while (cpos != NULL) @@ -4738,8 +4864,12 @@ run (void *cls, GNUNET_assert (NULL != transport); stats = GNUNET_STATISTICS_create ("core", cfg); - GNUNET_STATISTICS_set (stats, gettext_noop ("# discarded CORE_SEND requests"), 0, GNUNET_NO); - GNUNET_STATISTICS_set (stats, gettext_noop ("# discarded lower priority CORE_SEND requests"), 0, GNUNET_NO); + GNUNET_STATISTICS_set (stats, + gettext_noop ("# discarded CORE_SEND requests"), + 0, GNUNET_NO); + GNUNET_STATISTICS_set (stats, + gettext_noop ("# discarded lower priority CORE_SEND requests"), + 0, GNUNET_NO); mst = GNUNET_SERVER_mst_create (&deliver_message, NULL); diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index d31b67c95..e5e680d58 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -416,6 +416,16 @@ extern "C" */ #define GNUNET_MESSAGE_TYPE_CORE_HANGUP 85 +/** + * gzip-compressed type map of the sender + */ +#define GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP 86 + +/** + * uncompressed type map of the sender + */ +#define GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP 87 + /** * Message sent by datastore client on join. */