gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r25108 - gnunet/src/mesh


From: gnunet
Subject: [GNUnet-SVN] r25108 - gnunet/src/mesh
Date: Thu, 22 Nov 2012 19:02:19 +0100

Author: bartpolot
Date: 2012-11-22 19:02:19 +0100 (Thu, 22 Nov 2012)
New Revision: 25108

Modified:
   gnunet/src/mesh/
   gnunet/src/mesh/gnunet-service-mesh.c
   gnunet/src/mesh/mesh.h
   gnunet/src/mesh/mesh_api.c
Log:
- monitor tunnel inital implementation, WIP

Index: gnunet/src/mesh
===================================================================
--- gnunet/src/mesh     2012-11-22 17:03:48 UTC (rev 25107)
+++ gnunet/src/mesh     2012-11-22 18:02:19 UTC (rev 25108)

Property changes on: gnunet/src/mesh
___________________________________________________________________
Modified: svn:ignore
## -1,4 +1,5 ##
 gnunet-service-regexprofiler
+gnunet-daemon-regexprofiler
 gnunet-service-mesh-new
 gnunet-service-mesh_new
 mesh.conf
## -29,3 +30,4 ##
 Makefile
 .deps
 gnunet-service-mesh
+gnunet-mesh
Modified: gnunet/src/mesh/gnunet-service-mesh.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh.c       2012-11-22 17:03:48 UTC (rev 
25107)
+++ gnunet/src/mesh/gnunet-service-mesh.c       2012-11-22 18:02:19 UTC (rev 
25108)
@@ -1186,7 +1186,7 @@
  * @return tunnel handler, NULL if doesn't exist.
  */
 static struct MeshTunnel *
-tunnel_get (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid);
+tunnel_get (const struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid);
 
 
 /**
@@ -3237,7 +3237,7 @@
  * @return tunnel handler, NULL if doesn't exist
  */
 static struct MeshTunnel *
-tunnel_get (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid)
+tunnel_get (const struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid)
 {
   return tunnel_get_by_pi (GNUNET_PEER_search (oid), tid);
 }
@@ -8066,6 +8066,7 @@
 }
 
 
+
 /**
  * Iterator over all tunnels to send a monitoring client info about each 
tunnel.
  *
@@ -8076,44 +8077,44 @@
  * @return GNUNET_YES, to keep iterating.
  */
 static int
-monitor_tunnel_iterator (void *cls,
-                         const struct GNUNET_HashCode * key,
-                         void *value)
+monitor_all_tunnels_iterator (void *cls,
+                              const struct GNUNET_HashCode * key,
+                              void *value)
 {
   struct GNUNET_SERVER_Client *client = cls;
   struct MeshTunnel *t = value;
   struct GNUNET_MESH_LocalMonitor *msg;
   uint32_t npeers;
-
+  
   npeers = GNUNET_CONTAINER_multihashmap_size (t->peers);
   msg = GNUNET_malloc (sizeof(struct GNUNET_MESH_LocalMonitor) +
-                       npeers * sizeof (struct GNUNET_PeerIdentity));
+  npeers * sizeof (struct GNUNET_PeerIdentity));
   GNUNET_PEER_resolve(t->id.oid, &msg->owner);
   msg->tunnel_id = htonl (t->id.tid);
   msg->header.size = htons (sizeof (struct GNUNET_MESH_LocalMonitor) +
-                            npeers * sizeof (struct GNUNET_PeerIdentity));
+  npeers * sizeof (struct GNUNET_PeerIdentity));
   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR);
   msg->npeers = 0;
   (void) GNUNET_CONTAINER_multihashmap_iterate (t->peers,
                                                 monitor_peers_iterator,
                                                 msg);
-
+  
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "*  sending info about tunnel %s [%u] (%u peers)\n",
               GNUNET_i2s (&msg->owner), t->id.tid, npeers);
-
+  
   if (msg->npeers != npeers)
   {
     GNUNET_break (0);
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Monitor fail: size %u - iter %u\n",
                 npeers, msg->npeers);
   }
-
-  msg->npeers = htonl (npeers);
-  GNUNET_SERVER_notification_context_unicast (nc, client,
-                                              &msg->header,
-                                              GNUNET_NO);
-  return GNUNET_YES;
+  
+    msg->npeers = htonl (npeers);
+    GNUNET_SERVER_notification_context_unicast (nc, client,
+                                                &msg->header,
+                                                GNUNET_NO);
+    return GNUNET_YES;
 }
 
 
@@ -8142,7 +8143,7 @@
               "Received monitor request from client %u\n",
               c->id);
   GNUNET_CONTAINER_multihashmap_iterate (tunnels,
-                                         monitor_tunnel_iterator,
+                                         monitor_all_tunnels_iterator,
                                          client);
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Monitor request from client %u completed\n",
@@ -8152,6 +8153,170 @@
 
 
 /**
+ * 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
+{
+  /**
+   * Partial message, including peer count.
+   */
+  struct GNUNET_MESH_LocalMonitor *msg;
+
+  /**
+   * Array with parents: peer->parent.
+   */
+  GNUNET_PEER_Id *parents;
+
+  /**
+   * Array with positions: peer->position.
+   */
+  uint32_t *lookup;
+
+  /**
+   * Size of the message so far.
+   */
+  size_t size;
+
+  /**
+   * Client requesting the info.
+   */
+  struct MeshClient *c;
+};
+
+
+/**
+ * Send a client a message about 
+ */
+static void
+send_client_monitor_tunnel (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);
+  size += (sizeof (struct GNUNET_PeerIdentity) + sizeof (int)) * resp->npeers;
+  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]]);
+  GNUNET_SERVER_notification_context_unicast (nc, ctx->c->handle,
+                                              &resp->header, GNUNET_NO);
+}
+
+/**
+ * Iterator over a tunnel tree to build a message containing all peers
+ * the in the tunnel, including relay nodes.
+ *
+ * @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)
+{
+  struct MeshMonitorTunnelContext *ctx = cls;
+  struct GNUNET_MESH_LocalMonitor *msg = ctx->msg;
+  struct GNUNET_PeerIdentity *pid;
+
+  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);
+  msg->npeers++;
+
+  if ( (ctx->size + 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;
+  }
+}
+
+
+/**
+ * Handler for client's MONITOR_TUNNEL request.
+ *
+ * @param cls Closure (unused).
+ * @param client Identification of the client.
+ * @param message The actual message.
+ */
+static void
+handle_local_monitor_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
+                             const struct GNUNET_MessageHeader *message)
+{
+  const struct GNUNET_MESH_LocalMonitor *msg;
+  struct GNUNET_MESH_LocalMonitor *resp;
+  struct MeshMonitorTunnelContext ctx;
+  struct MeshClient *c;
+  struct MeshTunnel *t;
+
+  /* Sanity check for client registration */
+  if (NULL == (c = client_get (client)))
+  {
+    GNUNET_break (0);
+    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    return;
+  }
+
+  msg = (struct GNUNET_MESH_LocalMonitor *) message;
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Received monitor tunnel  request from client %u\n",
+              c->id);
+  t = tunnel_get (&msg->owner, ntohl (msg->tunnel_id));
+  if (NULL == t)
+  {
+    /* We don't know the tunnel */
+    struct GNUNET_MESH_LocalMonitor warn;
+
+    warn = *msg;
+    warn.npeers = htonl (UINT_MAX);
+    GNUNET_SERVER_notification_context_unicast (nc, client,
+                                                &warn.header,
+                                                GNUNET_NO);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    return;
+  }
+
+  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.c = c;
+
+  tree_iterate_all (t->tree,
+                    monitor_tunnel_iterator,
+                    &ctx);
+  send_client_monitor_tunnel (&ctx);
+
+  GNUNET_free (ctx.parents);
+  GNUNET_free (ctx.lookup);
+  GNUNET_free (resp);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Monitor tunnel request from client %u completed\n",
+              c->id);
+  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
+
+
+/**
  * Functions to handle messages from clients
  */
 static struct GNUNET_SERVER_MessageHandler client_handlers[] = {
@@ -8206,6 +8371,9 @@
   {&handle_local_monitor, NULL,
    GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR,
    sizeof (struct GNUNET_MessageHeader)},
+  {&handle_local_monitor_tunnel, NULL,
+   GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR_TUNNEL,
+     sizeof (struct GNUNET_MESH_LocalMonitor)},
   {NULL, NULL, 0, 0}
 };
 

Modified: gnunet/src/mesh/mesh.h
===================================================================
--- gnunet/src/mesh/mesh.h      2012-11-22 17:03:48 UTC (rev 25107)
+++ gnunet/src/mesh/mesh.h      2012-11-22 18:02:19 UTC (rev 25108)
@@ -305,7 +305,7 @@
 struct GNUNET_MESH_LocalMonitor
 {
   /**
-   * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR
+     * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR[_TUNNEL]
    */
   struct GNUNET_MessageHeader header;
 

Modified: gnunet/src/mesh/mesh_api.c
===================================================================
--- gnunet/src/mesh/mesh_api.c  2012-11-22 17:03:48 UTC (rev 25107)
+++ gnunet/src/mesh/mesh_api.c  2012-11-22 18:02:19 UTC (rev 25108)
@@ -217,6 +217,16 @@
    */
   void *monitor_cls;
 
+  /**
+   * Tunnel callback.
+   */
+  GNUNET_MESH_MonitorTunnelCB tunnel_cb;
+
+  /**
+   * Tunnel callback closure.
+   */
+  void *tunnel_cls;
+
 #if DEBUG_ACK
   unsigned int acks_sent;
   unsigned int acks_recv;
@@ -1295,7 +1305,21 @@
 }
 
 
+
 /**
+ * Process a local monitor_tunnel reply, pass info to the user.
+ *
+ * @param h Mesh handle.
+ * @param message Message itself.
+ */
+static void
+process_monitor_tunnel (struct GNUNET_MESH_Handle *h,
+                        const struct GNUNET_MessageHeader *message)
+{
+}
+
+
+/**
  * Function to process all messages received from the service
  *
  * @param cls closure
@@ -1345,11 +1369,14 @@
   case GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR:
     process_monitor (h, msg);
     break;
+  case GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR_TUNNEL:
+    process_monitor_tunnel (h, msg);
+    break;
   default:
     /* We shouldn't get any other packages, log and ignore */
     LOG (GNUNET_ERROR_TYPE_WARNING,
-         "unsolicited message form service (type %hu)\n",
-         ntohs (msg->type));
+         "unsolicited message form service (type %s)\n",
+         GNUNET_MESH_DEBUG_M2S (ntohs (msg->type)));
   }
   LOG (GNUNET_ERROR_TYPE_DEBUG, "message processed\n");
   if (GNUNET_YES == h->in_receive)
@@ -2202,15 +2229,23 @@
 
 /**
  * Request information about the running mesh peer.
+ * The callback will be called for every tunnel known to the service,
+ * listing all peers that blong to the tunnel (active only).
  *
+ * If called again on the same handle, it will overwrite the previous
+ * callback and cls. To retrieve the cls, monitor_cancel must be
+ * called first.
+ *
+ * WARNING: unstable API, likely to change in the future!
+ *
  * @param h Handle to the mesh peer.
  * @param callback Function to call with the requested data.
- * @param monitor_cls Closure for @c callback.
+ * @param callback_cls Closure for @c callback.
  */
 void
 GNUNET_MESH_monitor (struct GNUNET_MESH_Handle *h,
                      GNUNET_MESH_MonitorCB callback,
-                     void *monitor_cls)
+                     void *callback_cls)
 {
   struct GNUNET_MessageHeader msg;
 
@@ -2218,7 +2253,7 @@
   msg.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR);
   send_packet (h, &msg, NULL);
   h->monitor_cb = callback;
-  h->monitor_cls = monitor_cls;
+  h->monitor_cls = callback_cls;
 
   return;
 }
@@ -2244,6 +2279,40 @@
 
 
 /**
+ * Request information about a specific tunnel of the running mesh peer.
+ *
+ * WARNING: unstable API, likely to change in the future!
+ *
+ * @param h Handle to the mesh peer.
+ * @param initiator ID of the owner of the tunnel.
+ * @param tunnel_number Tunnel number.
+ * @param callback Function to call with the requested data.
+ * @param callback_cls Closure for @c callback.
+ */
+void
+GNUNET_MESH_monitor_tunnel (struct GNUNET_MESH_Handle *h,
+                            struct GNUNET_PeerIdentity *initiator,
+                            unsigned int tunnel_number,
+                            GNUNET_MESH_MonitorTunnelCB callback,
+                            void *callback_cls)
+{
+  struct GNUNET_MESH_LocalMonitor msg;
+
+  msg.header.size = htons (sizeof (msg));
+  msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR_TUNNEL);
+  msg.npeers = htonl (0);
+  msg.owner = *initiator;
+  msg.tunnel_id = htonl (tunnel_number);
+  msg.reserved = 0;
+  send_packet (h, &msg.header, NULL);
+  h->tunnel_cb = callback;
+  h->tunnel_cls = callback_cls;
+
+  return;
+}
+
+
+/**
  * Transition API for tunnel ctx management
  */
 void




reply via email to

[Prev in Thread] Current Thread [Next in Thread]