From c03182d1e7b55b18d9a66cf890effb11c5dc7a45 Mon Sep 17 00:00:00 2001 From: Bart Polot Date: Tue, 4 Dec 2012 12:39:47 +0000 Subject: [PATCH] - changed mesh api for monitoring --- src/include/gnunet_protocols.h | 8 +-- src/mesh/gnunet-service-mesh.c | 115 +++++++++++++++++---------------- src/mesh/mesh_api.c | 92 +++++++++++++++++++++----- 3 files changed, 142 insertions(+), 73 deletions(-) diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 1c73dc74e..087f86ac5 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -891,14 +891,14 @@ extern "C" #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK 286 /** - * Local monitoring of service. + * Local information about all tunnels of service. */ -#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR 287 +#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS 287 /** - * Local monitoring of service of a specific tunnel. + * Local information of service about a specific tunnel. */ -#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR_TUNNEL 288 +#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL 288 /** * 640kb should be enough for everybody diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index 01f30156e..b41d7e570 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c @@ -8093,7 +8093,7 @@ monitor_all_tunnels_iterator (void *cls, msg->tunnel_id = htonl (t->id.tid); msg->header.size = htons (sizeof (struct GNUNET_MESH_LocalMonitor) + npeers * sizeof (struct GNUNET_PeerIdentity)); - msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR); + msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS); msg->npeers = 0; (void) GNUNET_CONTAINER_multihashmap_iterate (t->peers, monitor_peers_iterator, @@ -8106,14 +8106,14 @@ monitor_all_tunnels_iterator (void *cls, if (msg->npeers != npeers) { GNUNET_break (0); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Monitor fail: size %u - iter %u\n", + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Get tunnels fail: size %u - iter %u\n", npeers, msg->npeers); } msg->npeers = htonl (npeers); GNUNET_SERVER_notification_context_unicast (nc, client, - &msg->header, - GNUNET_NO); + &msg->header, GNUNET_NO); return GNUNET_YES; } @@ -8126,8 +8126,8 @@ monitor_all_tunnels_iterator (void *cls, * @param message The actual message. */ static void -handle_local_monitor (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +handle_local_get_tunnels (void *cls, struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) { struct MeshClient *c; @@ -8140,13 +8140,13 @@ handle_local_monitor (void *cls, struct GNUNET_SERVER_Client *client, } GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Received monitor request from client %u\n", + "Received get tunnels request from client %u\n", c->id); GNUNET_CONTAINER_multihashmap_iterate (tunnels, monitor_all_tunnels_iterator, client); GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Monitor request from client %u completed\n", + "Get tunnels request from client %u completed\n", c->id); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -8154,9 +8154,6 @@ handle_local_monitor (void *cls, struct GNUNET_SERVER_Client *client, /** * Data needed to build a Monitor_Tunnel message. - * - * Both arrays can be combined to look up the position of the parent of - * a peer: lookup[parent[peer]]. */ struct MeshMonitorTunnelContext { @@ -8166,19 +8163,20 @@ struct MeshMonitorTunnelContext struct GNUNET_MESH_LocalMonitor *msg; /** - * Array with parents: peer->parent. + * Hashmap with positions: peer->position. */ - GNUNET_PEER_Id *parents; + struct GNUNET_CONTAINER_MultiHashMap *lookup; /** - * Array with positions: peer->position. + * Index of the parent of each peer in the message, realtive to the absolute + * order in the array (can be in a previous message). */ - uint32_t *lookup; + uint32_t parents[1024]; /** - * Size of the message so far. + * Peers visited so far in the tree, aka position of the current peer. */ - size_t size; + unsigned int npeers; /** * Client requesting the info. @@ -8188,15 +8186,17 @@ struct MeshMonitorTunnelContext /** - * Send a client a message about + * Send a client a message about the structure of a tunnel. + * + * @param ctx Context of the tunnel iteration, with info regarding the state + * of the execution and the number of peers visited for this message. */ static void -send_client_monitor_tunnel (struct MeshMonitorTunnelContext *ctx) +send_client_tunnel_info (struct MeshMonitorTunnelContext *ctx) { struct GNUNET_MESH_LocalMonitor *resp = ctx->msg; struct GNUNET_PeerIdentity *pid; unsigned int *parent; - unsigned int i; size_t size; size = sizeof (struct GNUNET_MESH_LocalMonitor); @@ -8204,8 +8204,7 @@ send_client_monitor_tunnel (struct MeshMonitorTunnelContext *ctx) resp->header.size = htons (size); pid = (struct GNUNET_PeerIdentity *) &resp[1]; parent = (unsigned int *) &pid[resp->npeers]; - for (i = 0; i < resp->npeers; i++) - parent[i] = htonl (ctx->lookup[ctx->parents[i]]); + memcpy (parent, ctx->parents, sizeof(uint32_t) * resp->npeers); GNUNET_SERVER_notification_context_unicast (nc, ctx->c->handle, &resp->header, GNUNET_NO); } @@ -8217,32 +8216,39 @@ send_client_monitor_tunnel (struct MeshMonitorTunnelContext *ctx) * @param cls Closure (pointer to pointer of message being built). * @param peer Short ID of a peer. * @param parent Short ID of the @c peer 's parent. - * - * FIXME: limit iterating to a message size / split if necessary */ static void -monitor_tunnel_iterator (void *cls, - GNUNET_PEER_Id peer, - GNUNET_PEER_Id parent) +tunnel_tree_iterator (void *cls, + GNUNET_PEER_Id peer, + GNUNET_PEER_Id parent) { struct MeshMonitorTunnelContext *ctx = cls; - struct GNUNET_MESH_LocalMonitor *msg = ctx->msg; + struct GNUNET_MESH_LocalMonitor *msg; struct GNUNET_PeerIdentity *pid; + struct GNUNET_PeerIdentity ppid; msg = ctx->msg; pid = (struct GNUNET_PeerIdentity *) &msg[1]; - GNUNET_PEER_resolve(peer, &pid[msg->npeers]); - ctx->parents[msg->npeers] = parent; - ctx->lookup[peer] = msg->npeers; - ctx->size += sizeof (struct GNUNET_PeerIdentity) * sizeof (uint32_t); + GNUNET_PEER_resolve (peer, &pid[msg->npeers]); + GNUNET_CONTAINER_multihashmap_put (ctx->lookup, + &pid[msg->npeers].hashPubKey, + (void *) (long) ctx->npeers, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); + GNUNET_PEER_resolve (parent, &ppid); + ctx->parents[msg->npeers] = + htonl ((long) GNUNET_CONTAINER_multihashmap_get (ctx->lookup, + &ppid.hashPubKey)); + + ctx->npeers++; msg->npeers++; - if ( (ctx->size + sizeof (struct GNUNET_PeerIdentity) * sizeof (uint32_t)) - > USHRT_MAX ) + if (sizeof (struct GNUNET_MESH_LocalMonitor) + + (msg->npeers + 1) * + (sizeof (struct GNUNET_PeerIdentity) + sizeof (uint32_t)) + > USHRT_MAX) { - send_client_monitor_tunnel (ctx); - ctx->size = sizeof (struct GNUNET_MESH_LocalMonitor); - ctx->msg->npeers = 0; + send_client_tunnel_info (ctx); + msg->npeers = 0; } } @@ -8255,8 +8261,8 @@ monitor_tunnel_iterator (void *cls, * @param message The actual message. */ static void -handle_local_monitor_tunnel (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +handle_local_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) { const struct GNUNET_MESH_LocalMonitor *msg; struct GNUNET_MESH_LocalMonitor *resp; @@ -8274,8 +8280,10 @@ handle_local_monitor_tunnel (void *cls, struct GNUNET_SERVER_Client *client, msg = (struct GNUNET_MESH_LocalMonitor *) message; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Received monitor tunnel request from client %u\n", - c->id); + "Received tunnel info request from client %u for tunnel %s[%X]\n", + c->id, + &msg->owner, + ntohl (msg->tunnel_id)); t = tunnel_get (&msg->owner, ntohl (msg->tunnel_id)); if (NULL == t) { @@ -8291,22 +8299,21 @@ handle_local_monitor_tunnel (void *cls, struct GNUNET_SERVER_Client *client, return; } + /* Initialize context */ resp = GNUNET_malloc (USHRT_MAX); /* avoid realloc'ing on each step */ *resp = *msg; resp->npeers = 0; ctx.msg = resp; - ctx.parents = GNUNET_malloc (sizeof (GNUNET_PEER_Id) * 1024); /* hard limit anyway */ - ctx.lookup = GNUNET_malloc (sizeof (int) * 1024); - ctx.size = sizeof (struct GNUNET_MESH_LocalMonitor); + ctx.lookup = GNUNET_CONTAINER_multihashmap_create (4 * t->peers_total, + GNUNET_YES); ctx.c = c; - tree_iterate_all (t->tree, - monitor_tunnel_iterator, - &ctx); - send_client_monitor_tunnel (&ctx); + /* Collect and send information */ + tree_iterate_all (t->tree, &tunnel_tree_iterator, &ctx); + send_client_tunnel_info (&ctx); - GNUNET_free (ctx.parents); - GNUNET_free (ctx.lookup); + /* Free context */ + GNUNET_CONTAINER_multihashmap_destroy (ctx.lookup); GNUNET_free (resp); GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -8368,11 +8375,11 @@ static struct GNUNET_SERVER_MessageHandler client_handlers[] = { {&handle_local_ack, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK, sizeof (struct GNUNET_MESH_LocalAck)}, - {&handle_local_monitor, NULL, - GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR, + {&handle_local_get_tunnels, NULL, + GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS, sizeof (struct GNUNET_MessageHeader)}, - {&handle_local_monitor_tunnel, NULL, - GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR_TUNNEL, + {&handle_local_show_tunnel, NULL, + GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL, sizeof (struct GNUNET_MESH_LocalMonitor)}, {NULL, NULL, 0, 0} }; diff --git a/src/mesh/mesh_api.c b/src/mesh/mesh_api.c index 9ebc48536..0e49fd831 100644 --- a/src/mesh/mesh_api.c +++ b/src/mesh/mesh_api.c @@ -227,6 +227,16 @@ struct GNUNET_MESH_Handle */ void *tunnel_cls; + /** + * All the peer in the tunnel so far. + */ + struct GNUNET_PeerIdentity *peers; + + /** + * How many peers we have in this tunnel so far. + */ + unsigned int tunnel_npeers; + #if DEBUG_ACK unsigned int acks_sent; unsigned int acks_recv; @@ -1262,19 +1272,19 @@ process_ack (struct GNUNET_MESH_Handle *h, /** - * Process a local monitor reply, pass info to the user. + * Process a local reply about info on all tunnels, pass info to the user. * * @param h Mesh handle. * @param message Message itself. */ static void -process_monitor (struct GNUNET_MESH_Handle *h, - const struct GNUNET_MessageHeader *message) +process_get_tunnels (struct GNUNET_MESH_Handle *h, + const struct GNUNET_MessageHeader *message) { struct GNUNET_MESH_LocalMonitor *msg; uint32_t npeers; - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Monitor messasge received\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Get Tunnels messasge received\n"); if (NULL == h->tunnels_cb) { @@ -1284,13 +1294,13 @@ process_monitor (struct GNUNET_MESH_Handle *h, msg = (struct GNUNET_MESH_LocalMonitor *) message; npeers = ntohl (msg->npeers); - if (ntohs (message->size) != + if (ntohs (message->size) != (sizeof (struct GNUNET_MESH_LocalMonitor) + npeers * sizeof (struct GNUNET_PeerIdentity))) { GNUNET_break_op (0); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Monitor message: size %hu - expected %u (%u peers)\n", + "Get tunnels message: size %hu - expected %u (%u peers)\n", ntohs (message->size), sizeof (struct GNUNET_MESH_LocalMonitor) + npeers * sizeof (struct GNUNET_PeerIdentity), @@ -1313,9 +1323,60 @@ process_monitor (struct GNUNET_MESH_Handle *h, * @param message Message itself. */ static void -process_monitor_tunnel (struct GNUNET_MESH_Handle *h, - const struct GNUNET_MessageHeader *message) +process_show_tunnel (struct GNUNET_MESH_Handle *h, + const struct GNUNET_MessageHeader *message) { + struct GNUNET_MESH_LocalMonitor *msg; + struct GNUNET_PeerIdentity *new_peers; + uint32_t *new_parents; + size_t esize; + uint32_t npeers; + unsigned int i; + + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Show Tunnel messasge received\n"); + + if (NULL == h->tunnel_cb) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " ignored\n"); + return; + } + + /* Verify message sanity */ + msg = (struct GNUNET_MESH_LocalMonitor *) message; + npeers = ntohl (msg->npeers); + esize = sizeof (struct GNUNET_MESH_LocalMonitor); + esize += npeers * (sizeof (struct GNUNET_PeerIdentity) + sizeof (uint32_t)); + if (ntohs (message->size) != esize) + { + GNUNET_break_op (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Show tunnel message: size %hu - expected %u (%u peers)\n", + ntohs (message->size), + esize, + npeers); + + h->tunnel_cb (h->tunnel_cls, NULL, NULL); + h->tunnel_cb = NULL; + h->tunnel_cls = NULL; + h->tunnel_npeers = 0; + GNUNET_free_non_null (h->peers); + h->peers = NULL; + + return; + } + + new_peers = (struct GNUNET_PeerIdentity *) &msg[1]; + new_parents = (uint32_t *) &new_peers[npeers]; + + h->peers = GNUNET_realloc (h->peers, h->tunnel_npeers + npeers); + memcpy (&h->peers[h->tunnel_npeers], + new_peers, + npeers * sizeof (struct GNUNET_PeerIdentity)); + h->tunnel_npeers += npeers; + for (i = 0; i < npeers; i++) + h->tunnel_cb (h->tunnel_cls, + &new_peers[i], + &h->peers[new_parents[i]]); } @@ -1366,11 +1427,11 @@ msg_received (void *cls, const struct GNUNET_MessageHeader *msg) case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK: process_ack (h, msg); break; - case GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR: - process_monitor (h, msg); + case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS: + process_get_tunnels (h, msg); break; - case GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR_TUNNEL: - process_monitor_tunnel (h, msg); + case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL: + process_show_tunnel (h, msg); break; default: /* We shouldn't get any other packages, log and ignore */ @@ -1713,7 +1774,8 @@ GNUNET_MESH_disconnect (struct GNUNET_MESH_Handle *handle) { case GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT: case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY: - case GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR: + case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS: + case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL: break; default: GNUNET_break (0); @@ -2250,7 +2312,7 @@ GNUNET_MESH_get_tunnels (struct GNUNET_MESH_Handle *h, struct GNUNET_MessageHeader msg; msg.size = htons (sizeof (msg)); - msg.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR); + msg.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS); send_packet (h, &msg, NULL); h->tunnels_cb = callback; h->tunnels_cls = callback_cls; @@ -2299,7 +2361,7 @@ GNUNET_MESH_show_tunnel (struct GNUNET_MESH_Handle *h, struct GNUNET_MESH_LocalMonitor msg; msg.header.size = htons (sizeof (msg)); - msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR_TUNNEL); + msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL); msg.npeers = htonl (0); msg.owner = *initiator; msg.tunnel_id = htonl (tunnel_number); -- 2.25.1