-makefile for new test_stream_local (commented)
[oweals/gnunet.git] / src / transport / gnunet-transport.c
index 17a21dd28d2a918d3534cc97c9e1515c97b90805..6ef273c45456a87cad06db055c7b42e40ca79d43 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2009 Christian Grothoff (and other contributing authors)
+     (C) 2011 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
 /**
  * How long do we wait for the NAT test to report success?
+ * Should match NAT_SERVER_TIMEOUT in 'nat_test.c'.
  */
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
+#define RESOLUTION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
 
 /**
  * Which peer should we connect to?
@@ -75,6 +77,11 @@ static int iterate_connections;
  */
 static int test_configuration;
 
+/**
+ * Option -m.
+ */
+static int monitor_connections;
+
 /**
  * Option -n.
  */
@@ -116,6 +123,8 @@ static struct GNUNET_PeerIdentity pid;
  */
 static GNUNET_SCHEDULER_TaskIdentifier end;
 
+static struct GNUNET_CONTAINER_MultiHashMap *peers;
+
 /**
  * Selected level of verbosity.
  */
@@ -246,8 +255,9 @@ do_test_configuration (const struct GNUNET_CONFIGURATION_Handle *cfg)
                                              &plugins))
   {
     FPRINTF (stderr,
-             _
-             ("No transport plugins configured, peer will never communicate\n"), NULL);
+             "%s",
+            _
+             ("No transport plugins configured, peer will never communicate\n"));
     ret = 4;
     return;
   }
@@ -269,7 +279,7 @@ do_test_configuration (const struct GNUNET_CONFIGURATION_Handle *cfg)
       adv_port = bnd_port;
     if (NULL == resolver)
       resolver =
-          GNUNET_OS_start_process (NULL, NULL, "gnunet-service-resolver",
+         GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-resolver",
                                    "gnunet-service-resolver", NULL);
     resolver_users++;
     GNUNET_RESOLVER_connect (cfg);
@@ -437,50 +447,97 @@ notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
   traffic_received += ntohs (message->size);
 }
 
+struct ResolutionContext
+{
+  struct GNUNET_HELLO_Address *addrcp;
+
+  int printed;
+};
+
 void
 process_string (void *cls, const char *address)
 {
-  struct GNUNET_HELLO_Address *addrcp = cls;
+  struct ResolutionContext *rc = cls;
+  struct GNUNET_HELLO_Address *addrcp = rc->addrcp;
 
-  if ((address != NULL))
+  if (address != NULL)
   {
     FPRINTF (stdout, _("Peer `%s': %s %s\n"), GNUNET_i2s (&addrcp->peer), addrcp->transport_name, address);
+    rc->printed = GNUNET_YES;
   }
   else
   {
     /* done */
-    GNUNET_free (addrcp);
+    if (GNUNET_NO == rc->printed)
+      FPRINTF (stdout, _("Peer `%s': %s <unable to resolve address>\n"), GNUNET_i2s (&addrcp->peer), addrcp->transport_name);
+    GNUNET_free (rc->addrcp);
+    GNUNET_free (rc);
   }
 }
 
 /**
- * Function to call with a human-readable format of an address
+ * Function to call with a binary address
  *
  * @param cls closure
  * @param peer identity of the peer
- * @param transport name of the plugin
- * @param addr binary address
- * @param addrlen number of bytes in addr
+ * @param address binary address (NULL on disconnect)
  */
 static void
 process_address (void *cls, const struct GNUNET_PeerIdentity *peer,
                  const struct GNUNET_HELLO_Address *address)
 {
   const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
+  struct ResolutionContext *rc;
 
-  if ((address == NULL) || (peer == NULL))
+  if (peer == NULL)
   {
     /* done */
     return;
   }
 
+  if (address == NULL)
+  {
+    FPRINTF (stdout, _("Peer `%s' disconnected\n"), GNUNET_i2s (peer));
+    return;
+  }
+
+  rc = GNUNET_malloc(sizeof (struct ResolutionContext));
+  rc->addrcp = GNUNET_HELLO_address_copy(address);
+  rc->printed = GNUNET_NO;
+
+  GNUNET_assert (NULL != rc);
+
   /* Resolve address to string */
   GNUNET_TRANSPORT_address_to_string (cfg, address, numeric,
-                                      GNUNET_TIME_UNIT_MINUTES, &process_string,
-                                      GNUNET_HELLO_address_copy(address));
+                                      RESOLUTION_TIMEOUT, &process_string,
+                                      rc);
+}
+
+
+/**
+ * Task run in monitor mode when the user presses CTRL-C to abort.
+ * Stops monitoring activity.
+ * 
+ * @param cls the 'struct GNUNET_TRANSPORT_PeerIterateContext *'
+ * @param tc scheduler context
+ */
+static void
+shutdown_task (void *cls,
+              const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GNUNET_TRANSPORT_PeerIterateContext *pic = cls;
+
+  GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pic);
+
+  if (NULL != peers)
+  {
+    GNUNET_CONTAINER_multihashmap_destroy (peers);
+    peers = NULL;
+  }
 }
 
 
+
 /**
  * Main function that will be run by the scheduler.
  *
@@ -533,10 +590,22 @@ run (void *cls, char *const *args, const char *cfgfile,
   }
   if (iterate_connections)
   {
+    peers = GNUNET_CONTAINER_multihashmap_create (20);
     GNUNET_TRANSPORT_peer_get_active_addresses (cfg, NULL, GNUNET_YES,
-                                                GNUNET_TIME_UNIT_MINUTES,
+                                                TIMEOUT,
                                                 &process_address, (void *) cfg);
   }
+  if (monitor_connections)
+  {
+    struct GNUNET_TRANSPORT_PeerIterateContext *pic;
+
+    pic = GNUNET_TRANSPORT_peer_get_active_addresses (cfg, NULL, GNUNET_NO,
+                                                     GNUNET_TIME_UNIT_FOREVER_REL,
+                                                     &process_address, (void *) cfg);
+    GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
+                                 &shutdown_task,
+                                 pic);
+  }
 }
 
 
@@ -553,6 +622,12 @@ main (int argc, char *const *argv)
     {'i', "information", NULL,
      gettext_noop ("provide information about all current connections (once)"),
      0, &GNUNET_GETOPT_set_one, &iterate_connections},
+    {'m', "monitor", NULL,
+     gettext_noop ("provide information about all current connections (continuously)"),
+     0, &GNUNET_GETOPT_set_one, &monitor_connections},
+    {'n', "numeric", NULL,
+     gettext_noop ("do not resolve hostnames"),
+     0, &GNUNET_GETOPT_set_one, &numeric},
     {'s', "send", NULL,
      gettext_noop
      ("send data for benchmarking to the other peer (until CTRL-C)"),
@@ -560,9 +635,6 @@ main (int argc, char *const *argv)
     {'t', "test", NULL,
      gettext_noop ("test transport configuration (involves external server)"),
      0, &GNUNET_GETOPT_set_one, &test_configuration},
-    {'n', "numeric", NULL,
-     gettext_noop ("do not resolve hostnames"),
-     0, &GNUNET_GETOPT_set_one, &numeric},
     GNUNET_GETOPT_OPTION_VERBOSE (&verbosity),
     GNUNET_GETOPT_OPTION_END
   };