Extended test case, fixed bugs, refactored code and connection packet format. DHT...
authorBart Polot <bart@net.in.tum.de>
Thu, 8 Sep 2011 17:25:39 +0000 (17:25 +0000)
committerBart Polot <bart@net.in.tum.de>
Thu, 8 Sep 2011 17:25:39 +0000 (17:25 +0000)
src/mesh/Makefile.am
src/mesh/gnunet-service-mesh.c
src/mesh/mesh.h
src/mesh/mesh_api_new.c
src/mesh/test_mesh.conf
src/mesh/test_mesh_local.c

index f49b3e326aaddb40a488f9e1370d9cee7dd1578d..0c7d598d422d280747332d76319e05567a11ab8b 100644 (file)
@@ -77,7 +77,7 @@ test_mesh_small_DEPENDENCIES = \
   libgnunetmeshnew.la
 
 if ENABLE_TEST_RUN
-TESTS = test_mesh_api test_mesh_local
+TESTS = test_mesh_api
 endif
 
 EXTRA_DIST = \
index 6ca5b3bec34146ccda527e85be5042d609704f11..9734fe4d9da9edaaf533c60298f3bd6ada53d852 100644 (file)
@@ -82,11 +82,11 @@ mesh_debug (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
                                     300)
 #define APP_ANNOUNCE_TIME       GNUNET_TIME_relative_multiply(\
                                     GNUNET_TIME_UNIT_SECONDS,\
-                                    60)
+                                    5)
 
 #define ID_ANNOUNCE_TIME        GNUNET_TIME_relative_multiply(\
                                     GNUNET_TIME_UNIT_SECONDS,\
-                                    300)
+                                    5)
 
 
 
@@ -833,10 +833,12 @@ announce_applications (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
     announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
     return;
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Starting PUT for %u apps\n",
+              n_apps);
   p = (unsigned int *) &buffer[8];
   for (i = 0; i < n_apps; i++)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Starting PUT for app %d\n",
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH:   Starting PUT for app %u\n",
                 applications[i]);
     *p = htonl (applications[i]);
     GNUNET_CRYPTO_hash (buffer, 12, &hash);
@@ -847,7 +849,7 @@ announce_applications (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
                                               APP_ANNOUNCE_TIME),
                     APP_ANNOUNCE_TIME,
 #if MESH_DEBUG
-                    &mesh_debug, "MESH: DHT_put for apps completed\n");
+                    &mesh_debug, "DHT_put for apps completed\n");
 #else
                     NULL, NULL);
 #endif
@@ -2018,7 +2020,7 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
       c = c->next;
       continue;
     }
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " matching client found, cleaning\n");
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: matching client found\n");
     GNUNET_CONTAINER_multihashmap_iterate (c->tunnels, &delete_tunnel_entry, c);
     GNUNET_CONTAINER_multihashmap_destroy (c->tunnels);
     if (0 != c->app_counter)
@@ -2072,8 +2074,10 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
 {
   struct GNUNET_MESH_ClientConnect *cc_msg;
   struct MeshClient *c;
+  GNUNET_MESH_ApplicationType *a;
   unsigned int size;
   uint16_t types;
+  uint16_t *t;
   uint16_t apps;
   uint16_t i;
   uint16_t j;
@@ -2096,45 +2100,52 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
   /* Create new client structure */
   c = GNUNET_malloc (sizeof (struct MeshClient));
   c->handle = client;
-  if (types != 0)
-  {
-    c->type_counter = types;
-    c->types = GNUNET_malloc (types * sizeof (uint16_t));
-    memcpy (c->types, &message[1], types * sizeof (uint16_t));
-  }
-  if (apps != 0)
+  a = (GNUNET_MESH_ApplicationType *) &cc_msg[1];
+  if (apps > 0)
   {
     c->app_counter = apps;
-    c->apps = GNUNET_malloc (apps * sizeof (GNUNET_MESH_ApplicationType));
-    memcpy (c->apps, &message[1] + types * sizeof (uint16_t),
-            apps * sizeof (GNUNET_MESH_ApplicationType));
-  }
-  for (i = 0; i < apps; i++)
-  {
-    known = GNUNET_NO;
-    for (j = 0; i < n_apps; j++)
+    c->apps = GNUNET_malloc (apps * sizeof(GNUNET_MESH_ApplicationType));
+    for (i = 0; i < apps; i++)
     {
-      if (c->apps[i] == applications[j])
+      c->apps[i] = ntohl(a[i]);
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "MESH:  app %u\n", c->apps[i]);
+      known = GNUNET_NO;
+      for (j = 0; i < n_apps; j++)
       {
-        known = GNUNET_YES;
-        applications_rc[j]++;
-        break;
+        if (c->apps[i] == applications[j])
+        {
+          known = GNUNET_YES;
+          applications_rc[j]++;
+          break;
+        }
       }
-    }
-    if (!known)
-    {
-      /* Register previously unknown application */
-      GNUNET_array_append (applications, n_apps, c->apps[i]);
-      n_apps--;
-      GNUNET_array_append (applications_rc, n_apps, 1);
-      if (GNUNET_SCHEDULER_NO_TASK == announce_applications_task)
+      if (!known)
       {
-        announce_applications_task =
-            GNUNET_SCHEDULER_add_delayed (APP_ANNOUNCE_TIME,
-                                          &announce_applications, NULL);
+        /* Register previously unknown application */
+        GNUNET_array_append (applications, n_apps, c->apps[i]);
+        n_apps--;
+        GNUNET_array_append (applications_rc, n_apps, 1);
+        if (GNUNET_SCHEDULER_NO_TASK == announce_applications_task)
+        {
+          announce_applications_task =
+              GNUNET_SCHEDULER_add_delayed (APP_ANNOUNCE_TIME,
+                                            &announce_applications, NULL);
+        }
+      /* TODO: if any client was looking for *type*, notify peer found  */
       }
     }
   }
+  if (types > 0)
+  {
+    t = (uint16_t *) &a[apps];
+    c->type_counter = types;
+    c->types = GNUNET_malloc (types * sizeof (uint16_t));
+    for (i =0; i < types; i++)
+    {
+      c->types[i] = ntohs(t[i]);
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "MESH:  type %hu\n", c->types[i]);
+    }
+  }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "MESH:  client has %u+%u subscriptions\n", c->type_counter,
               c->app_counter);
@@ -2439,6 +2450,7 @@ handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client,
   uint32_t *p;
   unsigned int i;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: got connect by type request\n");
   /* Sanity check for client registration */
   if (NULL == (c = retrieve_client (client)))
   {
@@ -2449,7 +2461,7 @@ handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client,
 
   connect_msg = (struct GNUNET_MESH_ConnectPeerByType *) message;
   /* Sanity check for message size */
-  if (sizeof (struct GNUNET_MESH_PeerControl) !=
+  if (sizeof (struct GNUNET_MESH_ConnectPeerByType) !=
       ntohs (connect_msg->header.size))
   {
     GNUNET_break (0);
@@ -2477,6 +2489,7 @@ handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client,
 
   /* Do WE have the service? */
   type = ntohl (connect_msg->type);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH:  type requested: %u\n", type);
   for (i = 0; i < n_apps; i++)
   {
     if (applications[i] == type)
@@ -2486,6 +2499,7 @@ handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client,
        */
       struct GNUNET_MESH_PeerControl pc;
 
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH:  available locally\n");
       pc.peer = my_full_id;
       GNUNET_CONTAINER_multihashmap_put (t->peers, &pc.peer.hashPubKey,
                                          get_peer_info (&pc.peer),
@@ -2493,7 +2507,13 @@ handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client,
       pc.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
       pc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD);
       pc.tunnel_id = htonl (t->local_tid);
-      GNUNET_SERVER_notification_context_unicast (nc, client, NULL, GNUNET_NO);
+      pc.peer = my_full_id;
+      GNUNET_SERVER_notification_context_unicast (nc,   /* context */
+                                                  client,       /* dest */
+                                                  &pc.header,   /* msg */
+                                                  GNUNET_NO);   /* can drop? */
+      GNUNET_SERVER_receive_done (client, GNUNET_OK);
+      return;
     }
   }
   /* Ok, lets find a peer offering the service */
index ca615f4e7ffe579640a8f253a67e941d1ff60397..62bcf678280df130204069f3c56bdd9a4e621abc 100644 (file)
@@ -84,14 +84,14 @@ struct GNUNET_MESH_ClientConnect
      * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT
      *
      * Size: sizeof(struct GNUNET_MESH_ClientConnect) +
-     *       sizeof(uint16_t) * types +
-     *       sizeof(MESH_ApplicationType) * applications
+     *       sizeof(MESH_ApplicationType) * applications +
+     *       sizeof(uint16_t) * types
      */
   struct GNUNET_MessageHeader header;
-  uint16_t types GNUNET_PACKED;
   uint16_t applications GNUNET_PACKED;
-  /* uint16_t                 list_types[types]           */
+  uint16_t types GNUNET_PACKED;
   /* uint16_t                 list_apps[applications]     */
+  /* uint16_t                 list_types[types]           */
 };
 
 
index ad8026d4af04542a577db24abd0469da26ef4922..f026575da642d253c93e0d06a95bdc98de006dd6 100644 (file)
@@ -593,6 +593,11 @@ reconnect (struct GNUNET_MESH_Handle *h)
   struct GNUNET_MESH_Tunnel *t;
   unsigned int i;
 
+#if DEBUG
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: *****************************\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: *******   RECONNECT   *******\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: *****************************\n");
+#endif
   h->in_receive = GNUNET_NO;
   /* disconnect */
   if (NULL != h->th)
@@ -1132,17 +1137,18 @@ GNUNET_MESH_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
     return NULL;
   }
   h->cls = cls;
-  h->message_handlers = handlers;
+  /* FIXME memdup? */
   h->applications = stypes;
+  h->message_handlers = handlers;
   h->next_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
   h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
 
   /* count handlers and apps, calculate size */
-  for (h->n_handlers = 0; handlers[h->n_handlers].type; h->n_handlers++) ;
   for (h->n_applications = 0; stypes[h->n_applications]; h->n_applications++) ;
+  for (h->n_handlers = 0; handlers[h->n_handlers].type; h->n_handlers++) ;
   size = sizeof (struct GNUNET_MESH_ClientConnect);
-  size += h->n_handlers * sizeof (uint16_t);
   size += h->n_applications * sizeof (GNUNET_MESH_ApplicationType);
+  size += h->n_handlers * sizeof (uint16_t);
 
   {
     char buf[size];
@@ -1151,12 +1157,15 @@ GNUNET_MESH_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
     msg = (struct GNUNET_MESH_ClientConnect *) buf;
     msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT);
     msg->header.size = htons (size);
-    types = (uint16_t *) & msg[1];
-    for (ntypes = 0; ntypes < h->n_handlers; ntypes++)
-      types[ntypes] = h->message_handlers[ntypes].type;
-    apps = (GNUNET_MESH_ApplicationType *) &types[ntypes];
+    apps = (GNUNET_MESH_ApplicationType *) &msg[1];
     for (napps = 0; napps < h->n_applications; napps++)
-      apps[napps] = h->applications[napps];
+    {
+      apps[napps] = htonl(h->applications[napps]);
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "mesh:  app %u\n", h->applications[napps]);
+    }
+    types = (uint16_t *) &apps[napps];
+    for (ntypes = 0; ntypes < h->n_handlers; ntypes++)
+      types[ntypes] = htons(h->message_handlers[ntypes].type);
     msg->applications = htons (napps);
     msg->types = htons (ntypes);
 #if DEBUG
index 6563073bc58e4b986f2f057e7848351b6d67ad31..e89e2bee225f2a7cc018b97be7147102b74de1d5 100644 (file)
@@ -10,6 +10,8 @@ AUTOSTART = YES
 ACCEPT_FROM = 127.0.0.1;
 HOSTNAME = localhost
 PORT = 10511
+#PREFIX = valgrind --leak-check=full
+#PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args
 
 [dht]
 DEBUG = NO
index 58ccad5e02f7f5f56e23e5afa92b65754a364880..6b5b2159b2f86616bc3eb41726b7934f4acd9a98 100644 (file)
 static struct GNUNET_OS_Process *arm_pid;
 static struct GNUNET_MESH_Handle *mesh_peer_1;
 static struct GNUNET_MESH_Handle *mesh_peer_2;
-static struct GNUNET_MESH_Tunnel *t_1;
+static struct GNUNET_MESH_Tunnel *t;
 
-// static struct GNUNET_MESH_Tunnel *t_2;
 static int result;
 static GNUNET_SCHEDULER_TaskIdentifier abort_task;
 static GNUNET_SCHEDULER_TaskIdentifier test_task;
 
 
+/**
+ * Shutdown nicely
+ */
+static void
+do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: shutdown\n");
+  if (0 != abort_task)
+  {
+    GNUNET_SCHEDULER_cancel (abort_task);
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: D1\n");
+  if (NULL != mesh_peer_1)
+  {
+    GNUNET_MESH_disconnect (mesh_peer_1);
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: D2\n");
+  if (NULL != mesh_peer_2)
+  {
+    GNUNET_MESH_disconnect (mesh_peer_2);
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: arm\n");
+  if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Wait\n");
+  GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (arm_pid));
+  GNUNET_OS_process_close (arm_pid);
+}
+
+
+/**
+ * Something went wrong and timed out. Kill everything and set error flag
+ */
+static void
+do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  if (0 != test_task)
+  {
+    GNUNET_SCHEDULER_cancel (test_task);
+  }
+  result = GNUNET_SYSERR;
+  abort_task = 0;
+  do_shutdown (cls, tc);
+}
+
+
 /**
  * Function is called whenever a message is received.
  *
@@ -62,6 +109,9 @@ data_callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx,
           const struct GNUNET_TRANSPORT_ATS_Information *atsi)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Data callback\n");
+  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
+                                (GNUNET_TIME_UNIT_SECONDS, 2), &do_shutdown,
+                                NULL);
   return GNUNET_OK;
 }
 
@@ -121,67 +171,49 @@ inbound_end (void *cls,
 
 
 /**
- * Handler array for traffic received on peer1
+ * Method called whenever a peer has disconnected from the tunnel.
+ *
+ * @param cls closure
+ * @param peer peer identity the tunnel stopped working with
  */
-static struct GNUNET_MESH_MessageHandler handlers1[] = {
-  {&data_callback, 1, 0},
-  {NULL, 0, 0}
-};
+static void peer_conected (
+    void *cls,
+    const struct GNUNET_PeerIdentity * peer)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: peer connected\n");
+}
 
 
 /**
- * Handler array for traffic received on peer2 (none expected)
+ * Method called whenever a peer has connected to the tunnel.
+ * 
+ * @param cls closure
+ * @param peer peer identity the tunnel was created to, NULL on timeout
+ * @param atsi performance data for the connection
  */
-static struct GNUNET_MESH_MessageHandler handlers2[] = { {NULL, 0, 0} };
-
+static void peer_disconnected (
+    void *cls,
+    const struct GNUNET_PeerIdentity * peer,
+    const struct GNUNET_TRANSPORT_ATS_Information * atsi)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: peer disconnected\n");
+}
 
 
 /**
- * Shutdown nicely
+ * Handler array for traffic received on peer1
  */
-static void
-do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: shutdown\n");
-  if (0 != abort_task)
-  {
-    GNUNET_SCHEDULER_cancel (abort_task);
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: D1\n");
-  if (NULL != mesh_peer_1)
-  {
-    GNUNET_MESH_disconnect (mesh_peer_1);
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: D2\n");
-  if (NULL != mesh_peer_2)
-  {
-    GNUNET_MESH_disconnect (mesh_peer_2);
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: arm\n");
-  if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM))
-  {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Wait\n");
-  GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (arm_pid));
-  GNUNET_OS_process_close (arm_pid);
-}
+static struct GNUNET_MESH_MessageHandler handlers1[] = {
+  {&data_callback, 1, 0},
+  {NULL, 0, 0}
+};
 
 
 /**
- * Something went wrong and timed out. Kill everything and set error flag
+ * Handler array for traffic received on peer2 (none expected)
  */
-static void
-do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  if (0 != test_task)
-  {
-    GNUNET_SCHEDULER_cancel (test_task);
-  }
-  result = GNUNET_SYSERR;
-  abort_task = 0;
-  do_shutdown (cls, tc);
-}
+static struct GNUNET_MESH_MessageHandler handlers2[] = { {NULL, 0, 0} };
+
 
 
 /**
@@ -191,8 +223,7 @@ static void
 test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct GNUNET_CONFIGURATION_Handle *cfg = cls;
-  static const GNUNET_MESH_ApplicationType app1[] =
-      { 1, 2, 3, 4, 5, 6, 7, 8, 0 };
+  static const GNUNET_MESH_ApplicationType app1[] = { 1, 0 };
   static const GNUNET_MESH_ApplicationType app2[] = { 0 };
 
   test_task = (GNUNET_SCHEDULER_TaskIdentifier) 0;
@@ -221,12 +252,14 @@ test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: YAY! CONNECTED TO MESH :D\n");
   }
 
-  t_1 = GNUNET_MESH_tunnel_create (mesh_peer_1, NULL, NULL, NULL, (void *) 1);
-//   t_2 = GNUNET_MESH_tunnel_create (mesh_peer_2, NULL, NULL, NULL, 2);
+  t = GNUNET_MESH_tunnel_create (mesh_peer_2,
+                                 NULL,
+                                 &peer_conected,
+                                 &peer_disconnected,
+                                 (void *) 2);
+  GNUNET_MESH_peer_request_connect_by_type(t, 1);
+
 
-  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
-                                (GNUNET_TIME_UNIT_SECONDS, 2), &do_shutdown,
-                                NULL);
 }