gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r10281 - gnunet/src/testing


From: gnunet
Subject: [GNUnet-SVN] r10281 - gnunet/src/testing
Date: Thu, 11 Feb 2010 14:37:09 +0100

Author: nevans
Date: 2010-02-11 14:37:09 +0100 (Thu, 11 Feb 2010)
New Revision: 10281

Modified:
   gnunet/src/testing/Makefile.am
   gnunet/src/testing/test_testing_connect.c
   gnunet/src/testing/test_testing_data_topology_clique.conf
   gnunet/src/testing/test_testing_topology_clique.c
   gnunet/src/testing/testing.c
   gnunet/src/testing/testing_group.c
Log:
testing changes, including real topology test (only for clique, and not that 
great of a test).  Need to verify it will run on other machines... also need to 
commit it since it currently works for me

Modified: gnunet/src/testing/Makefile.am
===================================================================
--- gnunet/src/testing/Makefile.am      2010-02-11 12:07:24 UTC (rev 10280)
+++ gnunet/src/testing/Makefile.am      2010-02-11 13:37:09 UTC (rev 10281)
@@ -60,4 +60,5 @@
 EXTRA_DIST = \
  test_testing_data.conf \
  test_testing_connect_peer1.conf \
- test_testing_connect_peer2.conf 
+ test_testing_connect_peer2.conf \
+ test_testing_data_topology_clique.conf

Modified: gnunet/src/testing/test_testing_connect.c
===================================================================
--- gnunet/src/testing/test_testing_connect.c   2010-02-11 12:07:24 UTC (rev 
10280)
+++ gnunet/src/testing/test_testing_connect.c   2010-02-11 13:37:09 UTC (rev 
10281)
@@ -64,6 +64,12 @@
   d2 = NULL;
 }
 
+static void
+finish_testing(void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+  GNUNET_TESTING_daemon_stop (d1, &end1_cb, NULL);
+  d1 = NULL;
+}
 
 static void
 my_connect_complete (void *cls,
@@ -75,8 +81,7 @@
                      struct GNUNET_TESTING_Daemon *second_daemon,
                      const char *emsg)
 {
-  GNUNET_TESTING_daemon_stop (d1, &end1_cb, NULL);
-  d1 = NULL;
+  GNUNET_SCHEDULER_add_now (sched, &finish_testing, NULL);
 }
 
 

Modified: gnunet/src/testing/test_testing_data_topology_clique.conf
===================================================================
--- gnunet/src/testing/test_testing_data_topology_clique.conf   2010-02-11 
12:07:24 UTC (rev 10280)
+++ gnunet/src/testing/test_testing_data_topology_clique.conf   2010-02-11 
13:37:09 UTC (rev 10281)
@@ -8,8 +8,9 @@
 [transport]
 PORT = 2565
 PLUGINS = tcp
-#PREFIX = xterm -e xterm -T transport -e gdb -x cmd --args
+#PREFIX = xterm -e xterm -T transport -e gdb --args
 #PREFIX = valgrind --tool=memcheck --log-file=logs%p
+#DEBUG = YES
 
 [arm]
 PORT = 2566
@@ -26,8 +27,10 @@
 
 [core]
 PORT = 2570
+#DEBUG = YES
 
 [testing]
-NUM_PEERS = 6
+NUM_PEERS = 2
 WEAKRANDOM = YES
 TOPOLOGY = 0
+F2F = YES

Modified: gnunet/src/testing/test_testing_topology_clique.c
===================================================================
--- gnunet/src/testing/test_testing_topology_clique.c   2010-02-11 12:07:24 UTC 
(rev 10280)
+++ gnunet/src/testing/test_testing_topology_clique.c   2010-02-11 13:37:09 UTC 
(rev 10281)
@@ -23,10 +23,10 @@
  */
 #include "platform.h"
 #include "gnunet_testing_lib.h"
+#include "gnunet_core_service.h"
 
 #define VERBOSE GNUNET_NO
 
-
 /**
  * How long until we give up on connecting the peers?
  */
@@ -38,8 +38,10 @@
 
 static unsigned long long num_peers;
 
-static int total_connections;
+static unsigned int total_connections;
 
+static unsigned int expected_connections;
+
 static int peers_left;
 
 static struct GNUNET_TESTING_PeerGroup *pg;
@@ -50,16 +52,239 @@
 
 GNUNET_SCHEDULER_TaskIdentifier die_task;
 
+static struct GNUNET_CORE_Handle *peer1handle;
 
+static struct GNUNET_CORE_Handle *peer2handle;
+
+#define MTYPE 12345
+
 static void
 finish_testing ()
 {
   GNUNET_assert (pg != NULL);
+
+  if (peer1handle != NULL)
+    GNUNET_CORE_disconnect(peer1handle);
+  if (peer2handle != NULL)
+    GNUNET_CORE_disconnect(peer2handle);
+
   GNUNET_TESTING_daemons_stop (pg);
   ok = 0;
 }
 
+static int
+process_mtype (void *cls,
+               const struct GNUNET_PeerIdentity *peer,
+               const struct GNUNET_MessageHeader *message,
+               struct GNUNET_TIME_Relative latency,
+               uint32_t distance)
+{
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Receiving message from `%4s'.\n", GNUNET_i2s (peer));
+#endif
+  GNUNET_SCHEDULER_cancel (sched, die_task);
+  GNUNET_SCHEDULER_add_now (sched, &finish_testing, NULL);
+  return GNUNET_OK;
+}
 
+
+static void
+connect_notify (void *cls,
+                const struct GNUNET_PeerIdentity *peer,
+                struct GNUNET_TIME_Relative latency,
+                uint32_t distance)
+{
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Encrypted connection established to peer `%4s' with latency 
%llu\n",
+              GNUNET_i2s (peer), latency.value);
+#endif
+}
+
+
+static void
+disconnect_notify (void *cls,
+                   const struct GNUNET_PeerIdentity *peer)
+{
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Encrypted connection to `%4s' cut\n", GNUNET_i2s (peer));
+#endif
+}
+
+
+static int
+inbound_notify (void *cls,
+                const struct GNUNET_PeerIdentity *other,
+                const struct GNUNET_MessageHeader *message,
+                struct GNUNET_TIME_Relative latency,
+                uint32_t distance)
+{
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Core provides inbound data from `%4s'.\n", GNUNET_i2s (other));
+#endif
+  return GNUNET_OK;
+}
+
+
+static int
+outbound_notify (void *cls,
+                 const struct GNUNET_PeerIdentity *other,
+                 const struct GNUNET_MessageHeader *message,
+                 struct GNUNET_TIME_Relative latency,
+                 uint32_t distance)
+{
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Core notifies about outbound data for `%4s'.\n",
+              GNUNET_i2s (other));
+#endif
+  return GNUNET_OK;
+}
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "End badly was called... stopping daemons.\n");
+#endif
+
+  if (peer1handle != NULL)
+    {
+      GNUNET_CORE_disconnect(peer1handle);
+      peer1handle = NULL;
+    }
+  if (peer2handle != NULL)
+    {
+      GNUNET_CORE_disconnect(peer2handle);
+      peer2handle = NULL;
+    }
+
+  if (pg != NULL)
+    {
+      GNUNET_TESTING_daemons_stop (pg);
+      ok = 7331;                /* Opposite of leet */
+    }
+  else
+    ok = 401;                   /* Never got peers started */
+}
+
+static size_t
+transmit_ready (void *cls, size_t size, void *buf)
+{
+  struct GNUNET_MessageHeader *m;
+
+  GNUNET_assert (buf != NULL);
+  m = (struct GNUNET_MessageHeader *) buf;
+  m->type = htons (MTYPE);
+  m->size = htons (sizeof (struct GNUNET_MessageHeader));
+  GNUNET_SCHEDULER_cancel(sched, die_task);
+  die_task =
+    GNUNET_SCHEDULER_add_delayed (sched,
+        TIMEOUT, &end_badly, "from transmit ready");
+
+  return sizeof (struct GNUNET_MessageHeader);
+}
+
+
+static struct GNUNET_CORE_MessageHandler handlers[] = {
+  {&process_mtype, MTYPE, sizeof (struct GNUNET_MessageHeader)},
+  {NULL, 0, 0}
+};
+
+
+static void
+init_notify (void *cls,
+             struct GNUNET_CORE_Handle *server,
+             const struct GNUNET_PeerIdentity *my_identity,
+             const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
+{
+  struct GNUNET_TESTING_Daemon *connected_peer = cls;
+  struct GNUNET_TESTING_Daemon *peer1;
+  struct GNUNET_TESTING_Daemon *peer2;
+
+  peer1 = GNUNET_TESTING_daemon_get(pg, 0);
+  peer2 = GNUNET_TESTING_daemon_get(pg, 1);
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Core connection to `%4s' established, setting up handles\n",
+              GNUNET_i2s (my_identity));
+#endif
+
+  if (connected_peer == peer1)
+    {
+      peer1handle = server;
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting core to peer 2\n");
+#endif
+      /* connect p2 */
+      GNUNET_CORE_connect (sched,
+                           peer2->cfg,
+                           TIMEOUT,
+                           peer2,
+                           &init_notify,
+                           NULL,
+                           &connect_notify,
+                           &disconnect_notify,
+                           &inbound_notify,
+                           GNUNET_YES,
+                           &outbound_notify, GNUNET_YES, handlers);
+    }
+  else
+    {
+      GNUNET_assert(connected_peer == peer2);
+      peer2handle = server;
+#if VERBOSE
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Asking core (1) for transmission to peer `%4s'\n",
+                  GNUNET_i2s (&peer2->id));
+#endif
+
+      if (NULL == GNUNET_CORE_notify_transmit_ready (peer1->server,
+                                                     0,
+                                                     TIMEOUT,
+                                                     &peer2->id,
+                                                     sizeof (struct 
GNUNET_MessageHeader),
+                                                     &transmit_ready, &peer1))
+        {
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                      "RECEIVED NULL when asking core (1) for transmission to 
peer `%4s'\n",
+                      GNUNET_i2s (&peer2->id));
+        }
+
+    }
+}
+
+
+static void
+send_test_messages ()
+{
+  struct GNUNET_TESTING_Daemon *peer1;
+  struct GNUNET_TESTING_Daemon *peer2;
+
+  peer1 = GNUNET_TESTING_daemon_get(pg, 0);
+  peer2 = GNUNET_TESTING_daemon_get(pg, 1);
+
+  die_task = GNUNET_SCHEDULER_add_delayed (sched,
+                                           TIMEOUT,
+                                           &end_badly, "from send test 
messages");
+
+  /* Send a message from peer 1 to peer 2 */
+  GNUNET_CORE_connect (sched,
+                       peer1->cfg,
+                       TIMEOUT,
+                       peer1,
+                       &init_notify,
+                       NULL,
+                       &connect_notify,
+                       &disconnect_notify,
+                       &inbound_notify,
+                       GNUNET_YES, &outbound_notify, GNUNET_YES, handlers);
+}
+
 void
 topology_callback (void *cls,
                    const struct GNUNET_PeerIdentity *first,
@@ -75,14 +300,17 @@
    * even though we know that X peers exist in i...  But we may want to
    * know about the peer for logging purposes here (I'm sure we will actually
    * so the API may need changed).  Question, should the API expose what
-   * a peer group is, or provide convenience/accessor functions? */
+   * a peer group is, or provide convenience/accessor functions?
+   *
+   * For now, I've added accessor functions, which seems like a software
+   * engineering kind of solution, but who knows/cares. */
   if (emsg == NULL)
     {
       total_connections++;
 #if VERBOSE
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connected peer %s to peer %s\n",
-               GNUNET_TESTING_daemon_get_shortname (first_daemon),
-               GNUNET_TESTING_daemon_get_shortname (second_daemon));
+               first_daemon->shortname,
+               second_daemon->shortname);
 #endif
     }
 #if VERBOSE
@@ -90,78 +318,37 @@
     {
 
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to connect peer %s to peer 
%s with error %s\n",
-               GNUNET_TESTING_daemon_get_shortname (first_daemon),
-               GNUNET_TESTING_daemon_get_shortname (second_daemon), emsg);
+               first_daemon->shortname,
+               second_daemon->shortname, emsg);
     }
 #endif
 
-  if (total_connections * 2 == num_peers * (num_peers - 1))
+  if (total_connections == expected_connections)
     {
 #if VERBOSE
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Created %d total connections, which is our target number!  
Ending test.\n",
-                  total_connections * 2);
+                  total_connections);
 #endif
+
       GNUNET_SCHEDULER_cancel (sched, die_task);
-      finish_testing ();
+      die_task = GNUNET_SCHEDULER_add_now (sched, &send_test_messages, NULL);
     }
   else
     {
 #if VERBOSE
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Have %d total connections, Need %d\n",
-                  total_connections * 2, num_peers * (num_peers - 1));
+                  total_connections, expected_connections);
 #endif
     }
 }
 
 
 static void
-end_badly ()
-{
-  GNUNET_SCHEDULER_cancel (sched, die_task);
-  if (pg != NULL)
-    {
-      GNUNET_TESTING_daemons_stop (pg);
-      ok = 7331;                /* Opposite of leet */
-    }
-  else
-    ok = 401;                   /* Never got peers started */
-}
-
-
-static void
 create_topology ()
 {
-  int expected_connections;     /* Is there any way we can use this to check
-                                   how many connections we are expecting to
-                                   finish the topology?  It would be nice so
-                                   that we could estimate completion time,
-                                   but since GNUNET_TESTING_create_topology
-                                   goes off and starts connecting we may get
-                                   the topology callback before we have
-                                   finished and not know how many!  We could
-                                   just never touch expected_connections,
-                                   and if we get called back when it's still
-                                   0 then we know we can't believe it.  I
-                                   don't like this though, because it may
-                                   technically be possible for all connections
-                                   to have been created and the callback
-                                   called without us setting
-                                   expected_connections!  Other options are
-                                   doing a trial connection setup, or
-                                   calculating the number of connections.
-                                   Problem with calculating is that for random
-                                   topologies this isn't reliable.  Problem
-                                   with counting is we then iterate over them
-                                   twice instead of once.  Probably the best
-                                   option though.  Grr, also doing trial
-                                   connection set up means we need to call
-                                   fake_topology_create and then
-                                   real_topology_create which is also ugly.
-                                   Then we need to maintain state inside pg as
-                                   well, which I was trying to avoid. */
-
+  expected_connections = -1;
   if ((pg != NULL) && (peers_left == 0))
     {
       /* create_topology will read the topology information from
@@ -178,11 +365,9 @@
     }
 
   GNUNET_SCHEDULER_cancel (sched, die_task);
-
   die_task = GNUNET_SCHEDULER_add_delayed (sched,
-                                           GNUNET_TIME_relative_multiply
-                                           (GNUNET_TIME_UNIT_SECONDS, 20),
-                                           &finish_testing, NULL);
+                                           TIMEOUT,
+                                           &end_badly, NULL);
 }
 
 
@@ -259,7 +444,7 @@
 static int
 check ()
 {
-  char *const argv[] = { "test-testing-topology",
+  char *const argv[] = { "test-testing-topology-clique",
     "-c",
     "test_testing_data_topology_clique.conf",
 #if VERBOSE
@@ -271,7 +456,7 @@
     GNUNET_GETOPT_OPTION_END
   };
   GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
-                      argv, "test-testing-topology", "nohelp",
+                      argv, "test-testing-topology-clique", "nohelp",
                       options, &run, &ok);
   return ok;
 }

Modified: gnunet/src/testing/testing.c
===================================================================
--- gnunet/src/testing/testing.c        2010-02-11 12:07:24 UTC (rev 10280)
+++ gnunet/src/testing/testing.c        2010-02-11 13:37:09 UTC (rev 10281)
@@ -54,162 +54,8 @@
  */
 #define MAX_EXEC_WAIT_RUNS 50
 
-/**
- * Phases of starting GNUnet on a system.
- */
-enum StartPhase
-{
-    /**
-     * Copy the configuration file to the target system.
-     */
-  SP_COPYING,
 
-    /**
-     * Configuration file has been copied, start ARM on target system.
-     */
-  SP_COPIED,
-
-    /**
-     * ARM has been started, check that it has properly daemonized and
-     * then try to connect to the CORE service (which should be
-     * auto-started by ARM).
-     */
-  SP_START_ARMING,
-
-    /**
-     * We're waiting for CORE to start.
-     */
-  SP_START_CORE,
-
-    /**
-     * Core has notified us that we've established a connection to the service.
-     * The main FSM halts here and waits to be moved to UPDATE or CLEANUP.
-     */
-  SP_START_DONE,
-
-    /**
-     * We've been asked to terminate the instance and are now waiting for
-     * the remote command to delete the configuration file to complete.
-     */
-  SP_CLEANUP,
-
-    /**
-     * We've received a configuration update and are currently waiting for
-     * the copy process for the update to complete.  Once it is, we will
-     * return to "SP_START_DONE" (and rely on ARM to restart all affected
-     * services).
-     */
-  SP_CONFIG_UPDATE
-};
-
-
 /**
- * Handle for a GNUnet daemon (technically a set of
- * daemons; the handle is really for the master ARM
- * daemon) started by the testing library.
- */
-struct GNUNET_TESTING_Daemon
-{
-  /**
-   * Our scheduler.
-   */
-  struct GNUNET_SCHEDULER_Handle *sched;
-
-  /**
-   * Our configuration.
-   */
-  struct GNUNET_CONFIGURATION_Handle *cfg;
-
-  /**
-   * Host to run GNUnet on.
-   */
-  char *hostname;
-
-  /* Result of GNUNET_i2s of this peer, for printing */
-  char *shortname;
-
-  /**
-   * Username we are using.
-   */
-  char *username;
-
-  /**
-   * Name of the configuration file
-   */
-  char *cfgfile;
-
-  /**
-   * Function to call when the peer is running.
-   */
-  GNUNET_TESTING_NotifyDaemonRunning cb;
-
-  /**
-   * Closure for cb.
-   */
-  void *cb_cls;
-
-  /**
-   * Arguments from "daemon_stop" call.
-   */
-  GNUNET_TESTING_NotifyCompletion dead_cb;
-
-  /**
-   * Closure for 'dead_cb'.
-   */
-  void *dead_cb_cls;
-
-  /**
-   * Arguments from "daemon_stop" call.
-   */
-  GNUNET_TESTING_NotifyCompletion update_cb;
-
-  /**
-   * Closure for 'update_cb'.
-   */
-  void *update_cb_cls;
-
-  /**
-   * Identity of this peer (once started).
-   */
-  struct GNUNET_PeerIdentity id;
-
-  /**
-   * Flag to indicate that we've already been asked
-   * to terminate (but could not because some action
-   * was still pending).
-   */
-  int dead;
-
-  /**
-   * PID of the process that we started last.
-   */
-  pid_t pid;
-
-  /**
-   * How many iterations have we been waiting for
-   * the started process to complete?
-   */
-  unsigned int wait_runs;
-
-  /**
-   * In which phase are we during the start of
-   * this process?
-   */
-  enum StartPhase phase;
-
-  /**
-   * ID of the current task.
-   */
-  GNUNET_SCHEDULER_TaskIdentifier task;
-
-  /**
-   * Handle to the server.
-   */
-  struct GNUNET_CORE_Handle *server;
-};
-
-
-/**
  * Function called after GNUNET_CORE_connect has succeeded
  * (or failed for good).  Note that the private key of the
  * peer is intentionally not exposed here; if you need it,
@@ -793,11 +639,21 @@
    */
   struct GNUNET_TESTING_Daemon *d1;
 
+  /*
+   * Handle to core of first daemon (to check connect)
+   */
+  struct GNUNET_CORE_Handle * d1core;
+
   /**
    * Testing handle to the second daemon.
    */
   struct GNUNET_TESTING_Daemon *d2;
 
+  /*
+   * Handle to core of second daemon (to check connect)
+   */
+  struct GNUNET_CORE_Handle * d2core;
+
   /**
    * Transport handle to the first daemon.
    */
@@ -830,10 +686,61 @@
    */
   struct GNUNET_TIME_Absolute timeout;
 
+  /*
+   * Hello timeout task
+   */
+  GNUNET_SCHEDULER_TaskIdentifier hello_send_task;
+
+  /*
+   * Connect timeout task
+   */
+  GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+
+  /**
+   * When should this operation be complete (or we must trigger
+   * a timeout).
+   */
+  struct GNUNET_TIME_Relative timeout_hello;
+
+  /*
+   * The current hello message we have (for d1)
+   */
+  struct GNUNET_MessageHeader *hello;
+
+  /*
+   * Was the connection successful?
+   */
+  int connected;
 };
 
 
 /**
+ * Receive the HELLO from one peer, give it to the other
+ * and ask them to connect.
+ *
+ * @param cls "struct ConnectContext"
+ * @param message HELLO message of peer
+ */
+static void
+process_hello (void *cls, const struct GNUNET_MessageHeader *message)
+{
+  struct ConnectContext *ctx = cls;
+
+#if DEBUG_TESTING
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Received `%s' from transport service of `%4s'\n",
+              "HELLO", GNUNET_i2s (&ctx->d1->id));
+#endif
+
+  GNUNET_assert (message != NULL);
+  GNUNET_free_non_null(ctx->hello);
+  ctx->hello = GNUNET_malloc(ntohs(message->size));
+  memcpy(ctx->hello, message, ntohs(message->size));
+
+}
+
+
+/**
  * Notify callback about success or failure of the attempt
  * to connect the two peers
  * 
@@ -846,16 +753,33 @@
 {
   struct ConnectContext *ctx = cls;
 
+  GNUNET_TRANSPORT_get_hello_cancel (ctx->d1th, &process_hello, ctx);
+  GNUNET_SCHEDULER_cancel(ctx->d1->sched, ctx->hello_send_task);
+
   if (ctx->cb != NULL)
     {
-      if ((tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT) != 0)
-        ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, ctx->d1->cfg,
-                 ctx->d2->cfg, ctx->d1, ctx->d2,
-                 _("Peers failed to connect"));
+      if (ctx->connected == GNUNET_NO)
+        {
+          ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, ctx->d1->cfg,
+                  ctx->d2->cfg, ctx->d1, ctx->d2,
+                  _("Peers failed to connect"));
+        }
       else
-        ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, ctx->d1->cfg,
-                 ctx->d2->cfg, ctx->d1, ctx->d2, NULL);
+        {
+          ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, ctx->d1->cfg,
+                   ctx->d2->cfg, ctx->d1, ctx->d2, NULL);
+          GNUNET_SCHEDULER_cancel(ctx->d1->sched, ctx->timeout_task);
+        }
     }
+
+  ctx->ntr = NULL;
+  GNUNET_TRANSPORT_disconnect (ctx->d1th);
+  ctx->d1th = NULL;
+  GNUNET_TRANSPORT_disconnect (ctx->d2th);
+  ctx->d2th = NULL;
+  GNUNET_CORE_disconnect (ctx->d1core);
+  ctx->d1core = NULL;
+
   GNUNET_free (ctx);
 }
 
@@ -868,74 +792,48 @@
  * @param buf where to copy the message, NULL on error
  * @return number of bytes copied to buf
  */
-static size_t
-transmit_ready (void *cls, size_t size, void *buf)
+static void
+connect_notify (void *cls, const struct GNUNET_PeerIdentity * peer, struct 
GNUNET_TIME_Relative latency,
+                uint32_t distance)
 {
   struct ConnectContext *ctx = cls;
 
 #if DEBUG_TESTING
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Core notified us about readiness to transmit message, 
connection must be up!\n");
+              "Core notified us about connection to a peer\n\n\n");
 #endif
-  ctx->ntr = NULL;
-  GNUNET_TRANSPORT_disconnect (ctx->d1th);
-  ctx->d1th = NULL;
-  GNUNET_TRANSPORT_disconnect (ctx->d2th);
-  ctx->d2th = NULL;
-  GNUNET_SCHEDULER_add_continuation (ctx->d1->sched,
-                                     &notify_connect_result,
-                                     ctx,
-                                     (buf == NULL) ?
-                                     GNUNET_SCHEDULER_REASON_TIMEOUT :
-                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
-  return 0;
-}
+  if (memcmp(&ctx->d2->id, peer, sizeof(struct GNUNET_PeerIdentity)) == 0)
+    {
+#if DEBUG_TESTING
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Core notified us about connection to peer %s\n\n\n", 
GNUNET_i2s(peer));
+#endif
+      /*
+       * If we disconnect here, then the hello may never get sent (if it was 
delayed!)
+       * However I'm sure there was a reason it was here... so I'm just 
commenting.
+       */
+      ctx->connected = GNUNET_YES;
+      GNUNET_SCHEDULER_add_now (ctx->d1->sched,
+                                &notify_connect_result,
+                                ctx);
+    }
 
-
-#if 0
-static void
-timeout_hello_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  GNUNET_TRANSPORT_get_hello_cancel (ctx->d1th, &process_hello, ctx);
-  GNUNET_TRANSPORT_disconnect (ctx->d1th);
-  GNUNET_TRANSPORT_disconnect (ctx->d2th);
-  if (NULL != ctx->cb)
-    ctx->cb (ctx->cb_cls, _("Failed to receive `HELLO' from peer\n"));
-  GNUNET_free (ctx);
 }
-#endif
 
-
-/**
- * Receive the HELLO from one peer, give it to the other
- * and ask them to connect.
- * 
- * @param cls "struct ConnectContext"
- * @param message HELLO message of peer
- */
 static void
-process_hello (void *cls, const struct GNUNET_MessageHeader *message)
+send_hello(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct ConnectContext *ctx = cls;
 
-  /* first of all, stop the notification stuff */
-  GNUNET_TRANSPORT_get_hello_cancel (ctx->d1th, &process_hello, ctx);
-#if DEBUG_TESTING
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Received `%s' from transport service of `%4s'\n",
-              "HELLO", GNUNET_i2s (&ctx->d1->id));
-#endif
-  GNUNET_assert (message != NULL);
-  GNUNET_TRANSPORT_offer_hello (ctx->d2th, message);
-  ctx->ntr
-    = GNUNET_CORE_notify_transmit_ready (ctx->d2->server,
-                                         0,
-                                         GNUNET_TIME_absolute_get_remaining
-                                         (ctx->timeout), &ctx->d1->id,
-                                         sizeof (struct GNUNET_MessageHeader),
-                                         &transmit_ready, ctx);
+  GNUNET_assert (ctx->hello != NULL);
+  GNUNET_TRANSPORT_offer_hello (ctx->d2th, ctx->hello);
+
+  ctx->timeout_hello = GNUNET_TIME_relative_multiply(ctx->timeout_hello, 2);
+  ctx->hello_send_task = GNUNET_SCHEDULER_add_delayed(ctx->d1->sched, 
ctx->timeout_hello, &send_hello, ctx);
 }
 
+
+#if HIDDEN
 /*
  * Accessor function since we have hidden what GNUNET_TESTING_Daemon is
  *
@@ -947,6 +845,32 @@
   return d->shortname;
 }
 
+char *
+GNUNET_TESTING_daemon_get_hostname (struct GNUNET_TESTING_Daemon *d)
+{
+  return d->hostname;
+}
+
+char *
+GNUNET_TESTING_daemon_get_username (struct GNUNET_TESTING_Daemon *d)
+{
+  return d->username;
+}
+
+struct GNUNET_PeerIdentity *
+GNUNET_TESTING_daemon_get_peer (struct GNUNET_TESTING_Daemon *d)
+{
+  return &d->id;
+}
+
+struct GNUNET_CONFIGURATION_Handle *
+GNUNET_TESTING_daemon_get_config (struct GNUNET_TESTING_Daemon *d)
+{
+  return d->cfg;
+}
+#endif
+
+
 /**
  * Establish a connection between two GNUnet daemons.
  *
@@ -965,6 +889,7 @@
                                 void *cb_cls)
 {
   struct ConnectContext *ctx;
+  static struct GNUNET_CORE_MessageHandler no_handlers[] = { {NULL, 0, 0} };
 
   if ((d1->server == NULL) || (d2->server == NULL))
     {
@@ -979,6 +904,8 @@
   ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
   ctx->cb = cb;
   ctx->cb_cls = cb_cls;
+  ctx->timeout_hello = 
GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 800);
+  ctx->connected = GNUNET_NO;
 #if DEBUG_TESTING
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Asked to connect peer %s to peer %s\n",
@@ -986,6 +913,24 @@
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Connecting to transport service of peer %s\n", d1->shortname);
 #endif
+
+  ctx->d1core = GNUNET_CORE_connect (d1->sched,
+                                     d1->cfg,
+                                     timeout,
+                                     ctx,
+                                     NULL,
+                                     NULL, &connect_notify, NULL,
+                                     NULL, GNUNET_NO,
+                                     NULL, GNUNET_NO, no_handlers);
+  if (ctx->d1core == NULL)
+    {
+      GNUNET_free (ctx);
+      if (NULL != cb)
+        cb (cb_cls, &d1->id, &d2->id, d1->cfg, d2->cfg, d1, d2,
+            _("Failed to connect to core service of first peer!\n"));
+      return;
+    }
+
   ctx->d1th = GNUNET_TRANSPORT_connect (d1->sched,
                                         d1->cfg, d1, NULL, NULL, NULL);
   if (ctx->d1th == NULL)
@@ -1004,6 +949,7 @@
               "Connecting to transport service of peer %s\n", d2->shortname);
 
 #endif
+
   ctx->d2th = GNUNET_TRANSPORT_connect (d2->sched,
                                         d2->cfg, d2, NULL, NULL, NULL);
   if (ctx->d2th == NULL)
@@ -1020,9 +966,13 @@
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Asking for hello from peer %s\n", GNUNET_i2s (&d1->id));
 #endif
-  /* FIXME: need to handle timeout: start timeout task 
-     as well here! (use 'timeout_hello_task') */
+
+  ctx->timeout_task = GNUNET_SCHEDULER_add_delayed (d1->sched,
+                                                    timeout,
+                                                    &notify_connect_result, 
ctx);
+
   GNUNET_TRANSPORT_get_hello (ctx->d1th, &process_hello, ctx);
+  ctx->hello_send_task = GNUNET_SCHEDULER_add_delayed(ctx->d1->sched, 
ctx->timeout_hello, &send_hello, ctx);
 }
 
 

Modified: gnunet/src/testing/testing_group.c
===================================================================
--- gnunet/src/testing/testing_group.c  2010-02-11 12:07:24 UTC (rev 10280)
+++ gnunet/src/testing/testing_group.c  2010-02-11 13:37:09 UTC (rev 10281)
@@ -46,6 +46,20 @@
 
 #define CONNECT_TIMEOUT GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_SECONDS, 60)
 
+struct PeerConnection
+{
+  /*
+   * Linked list
+   */
+  struct PeerConnection *next;
+
+  /*
+   * Pointer to daemon handle
+   */
+  struct GNUNET_TESTING_Daemon *daemon;
+
+};
+
 /**
  * Data we keep per peer.
  */
@@ -63,6 +77,12 @@
    * Handle for controlling the daemon.
    */
   struct GNUNET_TESTING_Daemon *daemon;
+
+  /*
+   * Linked list of peer connections (simply indexes of PeerGroup)
+   * FIXME: Question, store pointer or integer?  Pointer for now...
+   */
+  struct PeerConnection *connected_peers;
 };
 
 
@@ -202,7 +222,80 @@
   return uc.ret;
 }
 
+/*
+ * Add entries to the peers connected list
+ *
+ * @param pg the peer group we are working with
+ * @param first index of the first peer
+ * @param second index of the second peer
+ *
+ * @return the number of connections added (can be 0 1 or 2)
+ *
+ * FIXME: add both, or only add one?
+ *      - if both are added, then we have to keep track
+ *        when connecting so we don't double connect
+ *      - if only one is added, we need to iterate over
+ *        both lists to find out if connection already exists
+ *      - having both allows the whitelisting/friend file
+ *        creation to be easier
+ *
+ *      -- For now, add both, we have to iterate over each to
+ *         check for duplicates anyways, so we'll take the performance
+ *         hit assuming we don't have __too__ many connections
+ *
+ */
 static int
+add_connections(struct GNUNET_TESTING_PeerGroup *pg, unsigned int first, 
unsigned int second)
+{
+  int added;
+  struct PeerConnection *first_iter;
+  struct PeerConnection *second_iter;
+  int add_first;
+  int add_second;
+  struct PeerConnection *new_first;
+  struct PeerConnection *new_second;
+
+  first_iter = pg->peers[first].connected_peers;
+  add_first = GNUNET_YES;
+  while (first_iter != NULL)
+    {
+      if (first_iter->daemon == pg->peers[second].daemon)
+        add_first = GNUNET_NO;
+      first_iter = first_iter->next;
+    }
+
+  second_iter = pg->peers[second].connected_peers;
+  add_second = GNUNET_YES;
+  while (second_iter != NULL)
+    {
+      if (second_iter->daemon == pg->peers[first].daemon)
+        add_second = GNUNET_NO;
+      second_iter = second_iter->next;
+    }
+
+  added = 0;
+  if (add_first)
+    {
+      new_first = GNUNET_malloc(sizeof(struct PeerConnection));
+      new_first->daemon = pg->peers[second].daemon;
+      new_first->next = pg->peers[first].connected_peers;
+      pg->peers[first].connected_peers = new_first;
+      added++;
+    }
+
+  if (add_second)
+    {
+      new_second = GNUNET_malloc(sizeof(struct PeerConnection));
+      new_second->daemon = pg->peers[first].daemon;
+      new_second->next = pg->peers[second].connected_peers;
+      pg->peers[second].connected_peers = new_second;
+      added++;
+    }
+
+  return added;
+}
+
+static int
 create_clique (struct GNUNET_TESTING_PeerGroup *pg)
 {
   unsigned int outer_count;
@@ -221,12 +314,12 @@
                       "Connecting peer %d to peer %d\n",
                       outer_count, inner_count);
 #endif
-          GNUNET_TESTING_daemons_connect (pg->peers[outer_count].daemon,
+          connect_attempts += add_connections(pg, outer_count, inner_count);
+          /*GNUNET_TESTING_daemons_connect (pg->peers[outer_count].daemon,
                                           pg->peers[inner_count].daemon,
                                           CONNECT_TIMEOUT,
                                           pg->notify_connection,
-                                          pg->notify_connection_cls);
-          connect_attempts++;
+                                          pg->notify_connection_cls);*/
         }
     }
 
@@ -235,6 +328,111 @@
 
 
 /*
+ * Create the friend files based on the PeerConnection's
+ * of each peer in the peer group, and copy the files
+ * to the appropriate place
+ *
+ * @param pg the peer group we are dealing with
+ */
+static void
+create_and_copy_friend_files (struct GNUNET_TESTING_PeerGroup *pg)
+{
+  FILE *temp_friend_handle;
+  unsigned int pg_iter;
+  struct PeerConnection *connection_iter;
+  struct GNUNET_CRYPTO_HashAsciiEncoded peer_enc;
+  char *temp_service_path;
+  pid_t pid;
+  char *arg;
+  struct GNUNET_PeerIdentity *temppeer;
+  const char * mytemp;
+
+  for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
+    {
+      mytemp = GNUNET_DISK_mktemp("friends");
+      temp_friend_handle = fopen (mytemp, "wt");
+      connection_iter = pg->peers[pg_iter].connected_peers;
+      while (connection_iter != NULL)
+        {
+          temppeer = &connection_iter->daemon->id;
+          GNUNET_CRYPTO_hash_to_enc(&temppeer->hashPubKey, &peer_enc);
+          fprintf(temp_friend_handle, "%s\n", (char *)&peer_enc);
+          connection_iter = connection_iter->next;
+        }
+
+      fclose(temp_friend_handle);
+
+      GNUNET_CONFIGURATION_get_value_string(pg->peers[pg_iter].daemon->cfg, 
"PATHS", "SERVICEHOME", &temp_service_path);
+
+      if (temp_service_path == NULL)
+        {
+          GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                    _("No SERVICEHOME specified in peer configuration, can't 
copy friends file!\n"));
+          fclose(temp_friend_handle);
+          unlink(mytemp);
+          break;
+        }
+
+      if (pg->peers[pg_iter].daemon->hostname == NULL) /* Local, just copy the 
file */
+        {
+          GNUNET_asprintf (&arg, "%s/friends", temp_service_path);
+          pid = GNUNET_OS_start_process ("mv",
+                                         "mv", mytemp, arg, NULL);
+#if VERBOSE_TESTING
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                      _("Copying file with command cp %s %s\n"), mytemp, arg);
+#endif
+          GNUNET_free(arg);
+        }
+      else /* Remote, scp the file to the correct place */
+        {
+          if (NULL != pg->peers[pg_iter].daemon->username)
+            GNUNET_asprintf (&arg, "address@hidden:%s/friends", 
pg->peers[pg_iter].daemon->username, pg->peers[pg_iter].daemon->hostname, 
temp_service_path);
+          else
+            GNUNET_asprintf (&arg, "%s:%s/friends", 
pg->peers[pg_iter].daemon->hostname, temp_service_path);
+          pid = GNUNET_OS_start_process ("scp",
+                                         "scp", mytemp, arg, NULL);
+#if VERBOSE_TESTING
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                      _("Copying file with command scp %s %s\n"), mytemp, arg);
+#endif
+          GNUNET_free(arg);
+        }
+
+    }
+}
+
+
+
+/*
+ * Connect the topology as specified by the PeerConnection's
+ * of each peer in the peer group
+ *
+ * @param pg the peer group we are dealing with
+ */
+static void
+connect_topology (struct GNUNET_TESTING_PeerGroup *pg)
+{
+  unsigned int pg_iter;
+  struct PeerConnection *connection_iter;
+
+  for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
+    {
+      connection_iter = pg->peers[pg_iter].connected_peers;
+      while (connection_iter != NULL)
+        {
+          GNUNET_TESTING_daemons_connect (pg->peers[pg_iter].daemon,
+                                          connection_iter->daemon,
+                                          CONNECT_TIMEOUT,
+                                          pg->notify_connection,
+                                          pg->notify_connection_cls);
+          connection_iter = connection_iter->next;
+        }
+    }
+}
+
+
+/*
  * Takes a peer group and attempts to create a topology based on the
  * one specified in the configuration file.  Returns the number of connections
  * that will attempt to be created, but this will happen asynchronously(?) so
@@ -247,7 +445,6 @@
 int
 GNUNET_TESTING_create_topology (struct GNUNET_TESTING_PeerGroup *pg)
 {
-  /* Put stuff at home in here... */
   unsigned long long topology_num;
   int ret;
 
@@ -330,6 +527,11 @@
           ret = GNUNET_SYSERR;
           break;
         }
+
+      if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (pg->cfg, 
"TESTING", "F2F"))
+        create_and_copy_friend_files(pg);
+
+      connect_topology(pg);
     }
   else
     {
@@ -374,6 +576,7 @@
   const char *hostname;
   char *baseservicehome;
   char *newservicehome;
+  char *tmpdir;
   struct GNUNET_CONFIGURATION_Handle *pcfg;
   unsigned int off;
   unsigned int hostcnt;
@@ -475,7 +678,9 @@
         }
       else
         {
-          tempsize = snprintf (NULL, 0, "%s/%d/", 
"/tmp/gnunet-testing-test-test", off) + 1;    /* FIXME: set a default path, or 
read the TMPDIR variable or something */
+          tmpdir = getenv ("TMPDIR");
+          tmpdir = tmpdir ? tmpdir : "/tmp";
+          tempsize = snprintf (NULL, 0, "%s/%s/%d/", tmpdir, 
"gnunet-testing-test-test", off) + 1;
           newservicehome = GNUNET_malloc (tempsize);
           snprintf (newservicehome, tempsize, "%s/%d/",
                     "/tmp/gnunet-testing-test-test", off);
@@ -496,6 +701,18 @@
   return pg;
 }
 
+/*
+ * Get a daemon by number, so callers don't have to do nasty
+ * offsetting operation.
+ */
+struct GNUNET_TESTING_Daemon *
+GNUNET_TESTING_daemon_get (struct GNUNET_TESTING_PeerGroup *pg, unsigned int 
position)
+{
+  if (position < pg->total)
+    return pg->peers[position].daemon;
+  else
+    return NULL;
+}
 
 /**
  * Shutdown all peers started in the given group.
@@ -513,6 +730,7 @@
          continuations to be called here? This
          would require us to take a continuation
          as well... */
+
       if (NULL != pg->peers[off].daemon)
         GNUNET_TESTING_daemon_stop (pg->peers[off].daemon, NULL, NULL);
       if (NULL != pg->peers[off].cfg)





reply via email to

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