gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r23845 - in gnunet/src: core fs include mesh nse peerinfo-t


From: gnunet
Subject: [GNUnet-SVN] r23845 - in gnunet/src: core fs include mesh nse peerinfo-tool transport util
Date: Mon, 17 Sep 2012 12:45:23 +0200

Author: grothoff
Date: 2012-09-17 12:45:23 +0200 (Mon, 17 Sep 2012)
New Revision: 23845

Modified:
   gnunet/src/core/gnunet-service-core.c
   gnunet/src/core/gnunet-service-core_kx.c
   gnunet/src/core/gnunet-service-core_kx.h
   gnunet/src/fs/fs_uri.c
   gnunet/src/include/gnunet_crypto_lib.h
   gnunet/src/include/gnunet_server_lib.h
   gnunet/src/mesh/gnunet-service-mesh.c
   gnunet/src/nse/gnunet-service-nse.c
   gnunet/src/peerinfo-tool/gnunet-peerinfo.c
   gnunet/src/transport/gnunet-service-transport.c
   gnunet/src/transport/test_plugin_transport.c
   gnunet/src/util/crypto_random.c
   gnunet/src/util/crypto_rsa.c
   gnunet/src/util/gnunet-rsa.c
   gnunet/src/util/server.c
Log:
fixing #1551/#2503

Modified: gnunet/src/core/gnunet-service-core.c
===================================================================
--- gnunet/src/core/gnunet-service-core.c       2012-09-17 10:09:32 UTC (rev 
23844)
+++ gnunet/src/core/gnunet-service-core.c       2012-09-17 10:45:23 UTC (rev 
23845)
@@ -48,21 +48,39 @@
  */
 struct GNUNET_STATISTICS_Handle *GSC_stats;
 
+/**
+ * Handle to the server of the core service.
+ */
+static struct GNUNET_SERVER_Handle *GSC_server;
 
 /**
+ * Hostkey generation context
+ */
+struct GNUNET_CRYPTO_RsaKeyGenerationContext *GST_keygen;
+
+
+/**
  * Last task run during shutdown.  Disconnects us from
  * the transport.
+ * 
+ * @param cls NULL, unused
+ * @param tc scheduler context, unused
  */
 static void
-cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n");
+  if (NULL != GST_keygen)
+  {
+    GNUNET_CRYPTO_rsa_key_create_stop (GST_keygen);
+    GST_keygen = NULL;
+  }
   GSC_CLIENTS_done ();
   GSC_NEIGHBOURS_done ();
   GSC_SESSIONS_done ();
   GSC_KX_done ();
   GSC_TYPEMAP_done ();
-  if (GSC_stats != NULL)
+  if (NULL != GSC_stats)
   {
     GNUNET_STATISTICS_destroy (GSC_stats, GNUNET_NO);
     GSC_stats = NULL;
@@ -71,7 +89,43 @@
 }
 
 
+
 /**
+ * Callback for hostkey read/generation
+ *
+ * @param cls NULL
+ * @param pk the private key
+ * @param emsg error message
+ */
+static void
+key_generation_cb (void *cls,
+                   struct GNUNET_CRYPTO_RsaPrivateKey *pk,
+                   const char *emsg)
+{
+  GST_keygen = NULL;
+  if (NULL == pk)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+               _("Failed to read hostkey: %s\n"),
+               emsg);
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  if ((GNUNET_OK != GSC_KX_init (pk)) || 
+      (GNUNET_OK != GSC_NEIGHBOURS_init ()))
+  {
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  GSC_SESSIONS_init ();
+  GSC_CLIENTS_init (GSC_server);
+  GNUNET_SERVER_resume (GSC_server);
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Core service of `%4s' ready.\n"),
+              GNUNET_i2s (&GSC_my_identity));
+}
+
+
+/**
  * Initiate core service.
  *
  * @param cls closure
@@ -82,24 +136,36 @@
 run (void *cls, struct GNUNET_SERVER_Handle *server,
      const struct GNUNET_CONFIGURATION_Handle *c)
 {
+  char *keyfile;
+
   GSC_cfg = c;
+  GSC_server = server;
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_filename (GSC_cfg, "GNUNETD", "HOSTKEY",
+                                               &keyfile))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _
+                ("Core service is lacking HOSTKEY configuration setting.  
Exiting.\n"));
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
   GSC_stats = GNUNET_STATISTICS_create ("core", GSC_cfg);
-  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleaning_task,
+  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
                                 NULL);
+  GNUNET_SERVER_suspend (server);
   GSC_TYPEMAP_init ();
-  if ((GNUNET_OK != GSC_KX_init ()) || (GNUNET_OK != GSC_NEIGHBOURS_init ()))
+  GST_keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, 
&key_generation_cb, NULL);
+  GNUNET_free (keyfile);
+  if (NULL == GST_keygen)
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Transport service is unable to access hostkey. 
Exiting.\n"));
     GNUNET_SCHEDULER_shutdown ();
-    return;
   }
-  GSC_SESSIONS_init ();
-  GSC_CLIENTS_init (server);
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Core service of `%4s' ready.\n"),
-              GNUNET_i2s (&GSC_my_identity));
 }
 
 
-
 /**
  * The main function for the transport service.
  *

Modified: gnunet/src/core/gnunet-service-core_kx.c
===================================================================
--- gnunet/src/core/gnunet-service-core_kx.c    2012-09-17 10:09:32 UTC (rev 
23844)
+++ gnunet/src/core/gnunet-service-core_kx.c    2012-09-17 10:45:23 UTC (rev 
23845)
@@ -1686,30 +1686,13 @@
 /**
  * Initialize KX subsystem.
  *
+ * @param pk private key to use for the peer
  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
  */
 int
-GSC_KX_init ()
+GSC_KX_init (struct GNUNET_CRYPTO_RsaPrivateKey *pk)
 {
-  char *keyfile;
-
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (GSC_cfg, "GNUNETD", "HOSTKEY",
-                                               &keyfile))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _
-                ("Core service is lacking HOSTKEY configuration setting.  
Exiting.\n"));
-    return GNUNET_SYSERR;
-  }
-  my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
-  GNUNET_free (keyfile);
-  if (NULL == my_private_key)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Core service could not access hostkey.  Exiting.\n"));
-    return GNUNET_SYSERR;
-  }
+  my_private_key = pk;
   GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
   GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
                       &GSC_my_identity.hashPubKey);

Modified: gnunet/src/core/gnunet-service-core_kx.h
===================================================================
--- gnunet/src/core/gnunet-service-core_kx.h    2012-09-17 10:09:32 UTC (rev 
23844)
+++ gnunet/src/core/gnunet-service-core_kx.h    2012-09-17 10:45:23 UTC (rev 
23845)
@@ -121,10 +121,11 @@
 /**
  * Initialize KX subsystem.
  *
+ * @param pk private key to use for the peer
  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
  */
 int
-GSC_KX_init (void);
+GSC_KX_init (struct GNUNET_CRYPTO_RsaPrivateKey *pk);
 
 
 /**

Modified: gnunet/src/fs/fs_uri.c
===================================================================
--- gnunet/src/fs/fs_uri.c      2012-09-17 10:09:32 UTC (rev 23844)
+++ gnunet/src/fs/fs_uri.c      2012-09-17 10:45:23 UTC (rev 23845)
@@ -903,8 +903,7 @@
                 _("Lacking key configuration settings.\n"));
     return NULL;
   }
-  my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
-  if (my_private_key == NULL)
+  if (NULL == (my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file 
(keyfile)))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 _("Could not access hostkey file `%s'.\n"), keyfile);

Modified: gnunet/src/include/gnunet_crypto_lib.h
===================================================================
--- gnunet/src/include/gnunet_crypto_lib.h      2012-09-17 10:09:32 UTC (rev 
23844)
+++ gnunet/src/include/gnunet_crypto_lib.h      2012-09-17 10:45:23 UTC (rev 
23845)
@@ -1085,6 +1085,17 @@
 GNUNET_CRYPTO_random_disable_entropy_gathering (void);
 
 
+/**
+ * Check if we are using weak random number generation.
+ *
+ * @return GNUNET_YES if weak number generation is on
+ *         (thus will return YES if 
'GNUNET_CRYPTO_random_disable_entropy_gathering'
+ *          was called previously).
+ */
+int
+GNUNET_CRYPTO_random_is_weak (void);
+
+
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
 #endif

Modified: gnunet/src/include/gnunet_server_lib.h
===================================================================
--- gnunet/src/include/gnunet_server_lib.h      2012-09-17 10:09:32 UTC (rev 
23844)
+++ gnunet/src/include/gnunet_server_lib.h      2012-09-17 10:45:23 UTC (rev 
23845)
@@ -155,6 +155,24 @@
 
 
 /**
+ * Suspend accepting connections from the listen socket temporarily.
+ *
+ * @param server server to stop accepting connections.
+ */
+void
+GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server);
+
+
+/**
+ * Resume accepting connections from the listen socket.
+ *
+ * @param server server to stop accepting connections.
+ */
+void
+GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server);
+
+
+/**
  * Stop the listen socket and get ready to shutdown the server
  * once only 'monitor' clients are left.
  *

Modified: gnunet/src/mesh/gnunet-service-mesh.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh.c       2012-09-17 10:09:32 UTC (rev 
23844)
+++ gnunet/src/mesh/gnunet-service-mesh.c       2012-09-17 10:45:23 UTC (rev 
23845)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2001 - 2011 Christian Grothoff (and other contributing authors)
+     (C) 2001-2012 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
@@ -816,7 +816,13 @@
 static long long unsigned int max_tunnels;
 static long long unsigned int max_msgs_queue;
 
+
 /**
+ * Hostkey generation context
+ */
+static struct GNUNET_CRYPTO_RsaKeyGenerationContext *keygen;
+
+/**
  * DLL with all the clients, head.
  */
 static struct MeshClient *clients;
@@ -7684,6 +7690,7 @@
   return GNUNET_YES;
 }
 
+
 /**
  * Task run during shutdown.
  *
@@ -7700,6 +7707,11 @@
     GNUNET_CORE_disconnect (core_handle);
     core_handle = NULL;
   }
+ if (NULL != keygen)
+  {
+    GNUNET_CRYPTO_rsa_key_create_stop (keygen);
+    keygen = NULL;
+  }
   GNUNET_CONTAINER_multihashmap_iterate (tunnels, &shutdown_tunnel, NULL);
   GNUNET_CONTAINER_multihashmap_iterate (peers, &shutdown_peer, NULL);
   if (dht_handle != NULL)
@@ -7720,7 +7732,77 @@
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n");
 }
 
+
 /**
+ * Callback for hostkey read/generation
+ *
+ * @param cls NULL
+ * @param pk the private key
+ * @param emsg error message
+ */
+static void
+key_generation_cb (void *cls,
+                   struct GNUNET_CRYPTO_RsaPrivateKey *pk,
+                   const char *emsg)
+{
+  struct MeshPeerInfo *peer;
+  struct MeshPeerPath *p;
+
+  keygen = NULL;  
+  if (NULL == pk)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Mesh service could not access hostkey.  Exiting.\n"));
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  my_private_key = pk;
+  GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
+  GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
+                      &my_full_id.hashPubKey);
+  myid = GNUNET_PEER_intern (&my_full_id);
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Mesh for peer [%s] starting\n",
+              GNUNET_i2s(&my_full_id));
+
+//   transport_handle = GNUNET_TRANSPORT_connect(c,
+//                                               &my_full_id,
+//                                               NULL,
+//                                               NULL,
+//                                               NULL,
+//                                               NULL);
+
+
+
+  next_tid = 0;
+  next_local_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
+
+
+  GNUNET_SERVER_add_handlers (server_handle, client_handlers);
+  nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
+  GNUNET_SERVER_disconnect_notify (server_handle,
+                                   &handle_local_client_disconnect, NULL);
+
+
+  clients = NULL;
+  clients_tail = NULL;
+  next_client_id = 0;
+
+  announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
+  announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
+
+  /* Create a peer_info for the local peer */
+  peer = peer_info_get (&my_full_id);
+  p = path_new (1);
+  p->peers[0] = myid;
+  GNUNET_PEER_change_rc (myid, 1);
+  peer_info_add_path (peer, p, GNUNET_YES);
+  GNUNET_SERVER_resume (server_handle);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh service running\n");
+}
+
+
+/**
  * Process mesh requests.
  *
  * @param cls closure
@@ -7731,8 +7813,6 @@
 run (void *cls, struct GNUNET_SERVER_Handle *server,
      const struct GNUNET_CONFIGURATION_Handle *c)
 {
-  struct MeshPeerInfo *peer;
-  struct MeshPeerPath *p;
   char *keyfile;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n");
@@ -7873,76 +7953,28 @@
     dht_replication_level = 10;
   }
 
-  
-  my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
-  GNUNET_free (keyfile);
-  if (my_private_key == NULL)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Mesh service could not access hostkey.  Exiting.\n"));
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
-  GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
-  GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
-                      &my_full_id.hashPubKey);
-  myid = GNUNET_PEER_intern (&my_full_id);
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Mesh for peer [%s] starting\n",
-              GNUNET_i2s(&my_full_id));
+  tunnels = GNUNET_CONTAINER_multihashmap_create (32);
+  incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32);
+  peers = GNUNET_CONTAINER_multihashmap_create (32);
+  applications = GNUNET_CONTAINER_multihashmap_create (32);
+  types = GNUNET_CONTAINER_multihashmap_create (32);
 
-//   transport_handle = GNUNET_TRANSPORT_connect(c,
-//                                               &my_full_id,
-//                                               NULL,
-//                                               NULL,
-//                                               NULL,
-//                                               NULL);
-
   dht_handle = GNUNET_DHT_connect (c, 64);
-  if (dht_handle == NULL)
+  if (NULL == dht_handle)
   {
     GNUNET_break (0);
   }
-
   stats = GNUNET_STATISTICS_create ("mesh", c);
 
-
-  next_tid = 0;
-  next_local_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
-
-  tunnels = GNUNET_CONTAINER_multihashmap_create (32);
-  incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32);
-  peers = GNUNET_CONTAINER_multihashmap_create (32);
-  applications = GNUNET_CONTAINER_multihashmap_create (32);
-  types = GNUNET_CONTAINER_multihashmap_create (32);
-
-  GNUNET_SERVER_add_handlers (server_handle, client_handlers);
-  nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
-  GNUNET_SERVER_disconnect_notify (server_handle,
-                                   &handle_local_client_disconnect, NULL);
-
-
-  clients = NULL;
-  clients_tail = NULL;
-  next_client_id = 0;
-
-  announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
-  announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
-
-  /* Create a peer_info for the local peer */
-  peer = peer_info_get (&my_full_id);
-  p = path_new (1);
-  p->peers[0] = myid;
-  GNUNET_PEER_change_rc (myid, 1);
-  peer_info_add_path (peer, p, GNUNET_YES);
-
+  GNUNET_SERVER_suspend (server_handle);
   /* Scheduled the task to clean up when shutdown is called */
   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
                                 NULL);
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "end of run()\n");
+  keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, &key_generation_cb, 
NULL);
+  GNUNET_free (keyfile);
 }
 
+
 /**
  * The main function for the mesh service.
  *

Modified: gnunet/src/nse/gnunet-service-nse.c
===================================================================
--- gnunet/src/nse/gnunet-service-nse.c 2012-09-17 10:09:32 UTC (rev 23844)
+++ gnunet/src/nse/gnunet-service-nse.c 2012-09-17 10:45:23 UTC (rev 23845)
@@ -1,6 +1,6 @@
 /*
   This file is part of GNUnet.
-  (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors)
+  (C) 2009, 2010, 2011, 2012 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
@@ -304,8 +304,18 @@
  */
 static uint64_t my_proof;
 
+/**
+ * Handle to this serivce's server.
+ */
+static struct GNUNET_SERVER_Handle *srv;
 
 /**
+ * Hostkey generation context
+ */
+static struct GNUNET_CRYPTO_RsaKeyGenerationContext *keygen;
+
+
+/**
  * Initialize a message to clients with the current network
  * size estimate.
  *
@@ -576,7 +586,7 @@
         GNUNET_SCHEDULER_add_delayed (get_transmit_delay (0), 
&transmit_task_cb,
                                       peer_entry);
   }
-  if ((ntohl (size_estimate_messages[idx].hop_count) == 0) &&
+  if ((0 == ntohl (size_estimate_messages[idx].hop_count)) &&
       (GNUNET_SCHEDULER_NO_TASK != proof_task))
   {
     GNUNET_STATISTICS_update (stats,
@@ -584,7 +594,7 @@
                               1, GNUNET_NO);
     return 0;
   }
-  if (ntohs (size_estimate_messages[idx].header.size) == 0)
+  if (0 == ntohs (size_estimate_messages[idx].header.size))
   {
     GNUNET_STATISTICS_update (stats,
                               "# flood messages not generated (lack of 
history)",
@@ -661,7 +671,8 @@
  * @param ts timestamp to use
  */
 static void
-setup_flood_message (unsigned int slot, struct GNUNET_TIME_Absolute ts)
+setup_flood_message (unsigned int slot,
+                    struct GNUNET_TIME_Absolute ts)
 {
   struct GNUNET_NSE_FloodMessage *fm;
   uint32_t matching_bits;
@@ -699,7 +710,9 @@
  * @return GNUNET_OK (continue to iterate)
  */
 static int
-schedule_current_round (void *cls, const struct GNUNET_HashCode * key, void 
*value)
+schedule_current_round (void *cls, 
+                       const struct GNUNET_HashCode * key, 
+                       void *value)
 {
   struct NSEPeerEntry *peer_entry = value;
   struct GNUNET_TIME_Relative delay;
@@ -958,7 +971,7 @@
   struct NSEPeerEntry *peer_entry = value;
   struct GNUNET_TIME_Relative delay;
 
-  if (peer_entry->th != NULL)
+  if (NULL != peer_entry->th)
     return GNUNET_OK;           /* already active */
   if (peer_entry == exclude)
     return GNUNET_OK;           /* trigger of the update */
@@ -966,14 +979,14 @@
   {
     /* still stuck in previous round, no point to update, check that
      * we are active here though... */
-    if (GNUNET_SCHEDULER_NO_TASK == peer_entry->transmit_task &&
-        NULL == peer_entry->th)
+    if ( (GNUNET_SCHEDULER_NO_TASK == peer_entry->transmit_task) &&
+        (NULL == peer_entry->th) )
     {
         GNUNET_break (0);
     }
     return GNUNET_OK;
   }
-  if (peer_entry->transmit_task != GNUNET_SCHEDULER_NO_TASK)
+  if (GNUNET_SCHEDULER_NO_TASK != peer_entry->transmit_task)
   {
     GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
     peer_entry->transmit_task = GNUNET_SCHEDULER_NO_TASK;
@@ -1099,7 +1112,7 @@
       GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
       peer_entry->transmit_task = GNUNET_SCHEDULER_NO_TASK;
     }
-    if (peer_entry->th != NULL)
+    if (NULL != peer_entry->th)
     {
       GNUNET_CORE_notify_transmit_ready_cancel (peer_entry->th);
       peer_entry->th = NULL;
@@ -1228,7 +1241,7 @@
     GNUNET_SCHEDULER_cancel (pos->transmit_task);
     pos->transmit_task = GNUNET_SCHEDULER_NO_TASK;
   }
-  if (pos->th != NULL)
+  if (NULL != pos->th)
   {
     GNUNET_CORE_notify_transmit_ready_cancel (pos->th);
     pos->th = NULL;
@@ -1247,44 +1260,49 @@
 static void
 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  if (flood_task != GNUNET_SCHEDULER_NO_TASK)
+  if (GNUNET_SCHEDULER_NO_TASK != flood_task)
   {
     GNUNET_SCHEDULER_cancel (flood_task);
     flood_task = GNUNET_SCHEDULER_NO_TASK;
   }
-  if (proof_task != GNUNET_SCHEDULER_NO_TASK)
+  if (GNUNET_SCHEDULER_NO_TASK != proof_task)
   {
     GNUNET_SCHEDULER_cancel (proof_task);
     proof_task = GNUNET_SCHEDULER_NO_TASK;
     write_proof ();             /* remember progress */
   }
-  if (nc != NULL)
+  if (NULL != keygen)
   {
+    GNUNET_CRYPTO_rsa_key_create_stop (keygen);
+    keygen = NULL;
+  }
+  if (NULL != nc)
+  {
     GNUNET_SERVER_notification_context_destroy (nc);
     nc = NULL;
   }
-  if (coreAPI != NULL)
+  if (NULL != coreAPI)
   {
     GNUNET_CORE_disconnect (coreAPI);
     coreAPI = NULL;
   }
-  if (stats != NULL)
+  if (NULL != stats)
   {
     GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
     stats = NULL;
   }
-  if (peers != NULL)
+  if (NULL != peers)
   {
     GNUNET_CONTAINER_multihashmap_destroy (peers);
     peers = NULL;
   }
-  if (my_private_key != NULL)
+  if (NULL != my_private_key)
   {
     GNUNET_CRYPTO_rsa_key_free (my_private_key);
     my_private_key = NULL;
   }
 #if ENABLE_HISTOGRAM
-  if (wh != NULL)
+  if (NULL != wh)
   {
     GNUNET_break (GNUNET_OK == GNUNET_BIO_write_close (wh));
     wh = NULL;
@@ -1341,19 +1359,17 @@
 
 
 /**
- * Handle network size estimate clients.
+ * Callback for hostkey read/generation
  *
- * @param cls closure
- * @param server the initialized server
- * @param c configuration to use
+ * @param cls NULL
+ * @param pk the private key
+ * @param emsg error message
  */
 static void
-run (void *cls, struct GNUNET_SERVER_Handle *server,
-     const struct GNUNET_CONFIGURATION_Handle *c)
+key_generation_cb (void *cls,
+                   struct GNUNET_CRYPTO_RsaPrivateKey *pk,
+                   const char *emsg)
 {
-  char *keyfile;
-  char *proof;
-
   static const struct GNUNET_SERVER_MessageHandler handlers[] = {
     {&handle_start_message, NULL, GNUNET_MESSAGE_TYPE_NSE_START,
      sizeof (struct GNUNET_MessageHeader)},
@@ -1364,52 +1380,18 @@
      sizeof (struct GNUNET_NSE_FloodMessage)},
     {NULL, 0, 0}
   };
-  cfg = c;
+  char *proof;
 
-  if ((GNUNET_OK !=
-       GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "INTERVAL",
-                                            &gnunet_nse_interval)) ||
-      (GNUNET_OK !=
-       GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "WORKDELAY",
-                                            &proof_find_delay)) ||
-      (GNUNET_OK !=
-       GNUNET_CONFIGURATION_get_value_number (cfg, "NSE", "WORKBITS",
-                                              &nse_work_required)))
+  keygen = NULL;
+  if (NULL == pk)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _
-                ("NSE service is lacking key configuration settings.  
Exiting.\n"));
+                _("NSE service could not access hostkey: %s\n"),
+               emsg);
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
-  if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Invalid work requirement for NSE service. Exiting.\n"));
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
-
-
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", "HOSTKEY",
-                                               &keyfile))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _
-                ("NSE service is lacking key configuration settings.  
Exiting.\n"));
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
-  my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
-  GNUNET_free (keyfile);
-  if (my_private_key == NULL)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("NSE service could not access hostkey.  Exiting.\n"));
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
+  my_private_key = pk;
   GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
   GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
                       &my_identity.hashPubKey);
@@ -1419,11 +1401,8 @@
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 _
                 ("NSE service is lacking key configuration settings.  
Exiting.\n"));
-    if (my_private_key != NULL)
-    {
-      GNUNET_CRYPTO_rsa_key_free (my_private_key);
-      my_private_key = NULL;
-    }
+    GNUNET_CRYPTO_rsa_key_free (my_private_key);
+    my_private_key = NULL;    
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
@@ -1437,8 +1416,8 @@
                                           &find_proof, NULL);
 
   peers = GNUNET_CONTAINER_multihashmap_create (128);
-  GNUNET_SERVER_add_handlers (server, handlers);
-  nc = GNUNET_SERVER_notification_context_create (server, 1);
+  GNUNET_SERVER_add_handlers (srv, handlers);
+  nc = GNUNET_SERVER_notification_context_create (srv, 1);
   /* Connect to core service and register core handlers */
   coreAPI = GNUNET_CORE_connect (cfg,   /* Main configuration */
                                  NULL,       /* Closure passed to functions */
@@ -1450,8 +1429,11 @@
                                  NULL,  /* Don't want notified about all 
outbound messages */
                                  GNUNET_NO,     /* For header only outbound 
notification */
                                  core_handlers);        /* Register these 
handlers */
-  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
-                                NULL);
+  if (NULL == coreAPI)
+  {
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
 #if ENABLE_HISTOGRAM
   if (GNUNET_OK ==
       GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "HISTOGRAM", 
&proof))
@@ -1460,17 +1442,70 @@
     GNUNET_free (proof);
   }
 #endif
-  if (coreAPI == NULL)
+  stats = GNUNET_STATISTICS_create ("nse", cfg);
+  GNUNET_SERVER_resume (srv);
+}
+
+
+/**
+ * Handle network size estimate clients.
+ *
+ * @param cls closure
+ * @param server the initialized server
+ * @param c configuration to use
+ */
+static void
+run (void *cls, 
+     struct GNUNET_SERVER_Handle *server,
+     const struct GNUNET_CONFIGURATION_Handle *c)
+{
+  char *keyfile;
+
+  cfg = c;
+  srv = server;  
+  if ((GNUNET_OK !=
+       GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "INTERVAL",
+                                            &gnunet_nse_interval)) ||
+      (GNUNET_OK !=
+       GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "WORKDELAY",
+                                            &proof_find_delay)) ||
+      (GNUNET_OK !=
+       GNUNET_CONFIGURATION_get_value_number (cfg, "NSE", "WORKBITS",
+                                              &nse_work_required)))
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _
+                ("NSE service is lacking key configuration settings.  
Exiting.\n"));
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
-  stats = GNUNET_STATISTICS_create ("nse", cfg);
+  if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Invalid work requirement for NSE service. Exiting.\n"));
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", "HOSTKEY",
+                                               &keyfile))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _
+                ("NSE service is lacking key configuration settings.  
Exiting.\n"));
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
+                                NULL);
+  GNUNET_SERVER_suspend (srv);
+  keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, &key_generation_cb, 
NULL);
+  GNUNET_free (keyfile);
 }
 
 
 /**
- * The main function for the statistics service.
+ * The main function for the network size estimation service.
  *
  * @param argc number of arguments from the command line
  * @param argv command line arguments

Modified: gnunet/src/peerinfo-tool/gnunet-peerinfo.c
===================================================================
--- gnunet/src/peerinfo-tool/gnunet-peerinfo.c  2012-09-17 10:09:32 UTC (rev 
23844)
+++ gnunet/src/peerinfo-tool/gnunet-peerinfo.c  2012-09-17 10:45:23 UTC (rev 
23845)
@@ -394,10 +394,10 @@
   struct GNUNET_CRYPTO_HashAsciiEncoded enc;
   struct PrintContext *pc;
 
-  if (peer == NULL)
+  if (NULL == peer)
   {
     pic = NULL; /* end of iteration */
-    if (err_msg != NULL)
+    if (NULL != err_msg)
     {
       FPRINTF (stderr, 
               _("Error in communication with PEERINFO service: %s\n"),
@@ -812,13 +812,14 @@
   char *fn;
 
   cfg = c;
-  if (args[0] != NULL)
+  if (NULL != args[0])
   {
-    FPRINTF (stderr, _("Invalid command line argument `%s'\n"), args[0]);
+    FPRINTF (stderr, 
+            _("Invalid command line argument `%s'\n"), 
+            args[0]);
     return;
   }
-  peerinfo = GNUNET_PEERINFO_connect (cfg);
-  if (peerinfo == NULL)
+  if (NULL == (peerinfo = GNUNET_PEERINFO_connect (cfg)))
   {
     FPRINTF (stderr, "%s",  _("Could not access PEERINFO service.  
Exiting.\n"));
     return;
@@ -834,7 +835,6 @@
               "GNUNETD", "HOSTKEYFILE");
       return;
     }
-
     if (NULL == (priv = GNUNET_CRYPTO_rsa_key_create_from_file (fn)))
     {
       FPRINTF (stderr, _("Loading hostkey from `%s' failed.\n"), fn);

Modified: gnunet/src/transport/gnunet-service-transport.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport.c     2012-09-17 10:09:32 UTC 
(rev 23844)
+++ gnunet/src/transport/gnunet-service-transport.c     2012-09-17 10:45:23 UTC 
(rev 23845)
@@ -62,6 +62,16 @@
 struct GNUNET_PEERINFO_Handle *GST_peerinfo;
 
 /**
+ * Hostkey generation context
+ */
+struct GNUNET_CRYPTO_RsaKeyGenerationContext *GST_keygen;
+
+/**
+ * Handle to our service's server.
+ */
+static struct GNUNET_SERVER_Handle *GST_server;
+
+/**
  * Our public key.
  */
 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded GST_my_public_key;
@@ -271,7 +281,7 @@
     break;
   case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK:
     GST_neighbours_handle_session_ack (message, peer, &address, session, ats,
-                                       ats_count);
+                                      ats_count);
     break;
   case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT:
     GST_neighbours_handle_disconnect_message (peer, message);
@@ -539,6 +549,11 @@
 static void
 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
+  if (NULL != GST_keygen)
+  {
+    GNUNET_CRYPTO_rsa_key_create_stop (GST_keygen);
+    GST_keygen = NULL;
+  }
   GST_neighbours_stop ();
   GST_validation_stop ();
   GST_plugins_unload ();
@@ -549,17 +564,17 @@
   GST_blacklist_stop ();
   GST_hello_stop ();
 
-  if (GST_peerinfo != NULL)
+  if (NULL != GST_peerinfo)
   {
     GNUNET_PEERINFO_disconnect (GST_peerinfo);
     GST_peerinfo = NULL;
   }
-  if (GST_stats != NULL)
+  if (NULL != GST_stats)
   {
     GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO);
     GST_stats = NULL;
   }
-  if (GST_my_private_key != NULL)
+  if (NULL != GST_my_private_key)
   {
     GNUNET_CRYPTO_rsa_key_free (GST_my_private_key);
     GST_my_private_key = NULL;
@@ -568,41 +583,32 @@
 
 
 /**
- * Initiate transport service.
+ * Callback for hostkey read/generation
  *
- * @param cls closure
- * @param server the initialized server
- * @param c configuration to use
+ * @param cls NULL
+ * @param pk the private key
+ * @param emsg error message
  */
 static void
-run (void *cls, struct GNUNET_SERVER_Handle *server,
-     const struct GNUNET_CONFIGURATION_Handle *c)
+key_generation_cb (void *cls,
+                   struct GNUNET_CRYPTO_RsaPrivateKey *pk,
+                   const char *emsg)
 {
-  char *keyfile;
   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded tmp;
-  /* setup globals */
-  GST_cfg = c;
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (c, "GNUNETD", "HOSTKEY",
-                                               &keyfile))
+
+  GST_keygen = NULL;
+  if (NULL == pk)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _
-                ("Transport service is lacking key configuration settings.  
Exiting.\n"));
+                _("Transport service could not access hostkey: %s. 
Exiting.\n"),
+                emsg);
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
-  GST_my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
-  GNUNET_free (keyfile);
-  if (GST_my_private_key == NULL)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Transport service could not access hostkey.  Exiting.\n"));
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
-  GST_stats = GNUNET_STATISTICS_create ("transport", c);
-  GST_peerinfo = GNUNET_PEERINFO_connect (c);
+  GST_my_private_key = pk;
+
+  GST_stats = GNUNET_STATISTICS_create ("transport", GST_cfg);
+  GST_peerinfo = GNUNET_PEERINFO_connect (GST_cfg);
   memset (&GST_my_public_key, '\0', sizeof (GST_my_public_key));
   memset (&tmp, '\0', sizeof (tmp));
   GNUNET_CRYPTO_rsa_key_get_public (GST_my_private_key, &GST_my_public_key);
@@ -614,7 +620,7 @@
 
   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
                                 NULL);
-  if (GST_peerinfo == NULL)
+  if (NULL == GST_peerinfo)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 _("Could not access PEERINFO service.  Exiting.\n"));
@@ -625,7 +631,7 @@
   /* start subsystems */
   GST_hello_start (&process_hello_update, NULL);
   GNUNET_assert (NULL != GST_hello_get());
-  GST_blacklist_start (server);
+  GST_blacklist_start (GST_server);
   GST_ats =
       GNUNET_ATS_scheduling_init (GST_cfg, &ats_request_address_change, NULL);
   GST_plugins_load (&plugin_env_receive_callback,
@@ -636,12 +642,51 @@
                         &neighbours_connect_notification,
                         &neighbours_disconnect_notification,
                         &neighbours_address_notification);
-  GST_clients_start (server);
+  GST_clients_start (GST_server);
   GST_validation_start ();
+  GNUNET_SERVER_resume (GST_server);
 }
 
 
 /**
+ * Initiate transport service.
+ *
+ * @param cls closure
+ * @param server the initialized server
+ * @param c configuration to use
+ */
+static void
+run (void *cls, struct GNUNET_SERVER_Handle *server,
+     const struct GNUNET_CONFIGURATION_Handle *c)
+{
+  char *keyfile;
+
+  /* setup globals */
+  GST_cfg = c;
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_filename (c, "GNUNETD", "HOSTKEY",
+                                               &keyfile))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _
+                ("Transport service is lacking key configuration settings.  
Exiting.\n"));
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  GST_server = server;
+  GNUNET_SERVER_suspend (server);
+  GST_keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, 
&key_generation_cb, NULL);
+  GNUNET_free (keyfile);
+  if (NULL == GST_keygen)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Transport service is unable to access hostkey. 
Exiting.\n"));
+    GNUNET_SCHEDULER_shutdown ();
+  }
+}
+
+
+/**
  * The main function for the transport service.
  *
  * @param argc number of arguments from the command line

Modified: gnunet/src/transport/test_plugin_transport.c
===================================================================
--- gnunet/src/transport/test_plugin_transport.c        2012-09-17 10:09:32 UTC 
(rev 23844)
+++ gnunet/src/transport/test_plugin_transport.c        2012-09-17 10:45:23 UTC 
(rev 23845)
@@ -139,6 +139,7 @@
   char *addrstring;
 };
 
+
 static void
 end ()
 {
@@ -186,6 +187,7 @@
   }
 }
 
+
 static void
 end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
@@ -245,6 +247,7 @@
   ok = 1;
 }
 
+
 static void
 wait_end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
@@ -290,6 +293,7 @@
 
 static int got_reply;
 
+
 /**
  * Take the given address and append it to the set of results sent back to
  * the client.
@@ -435,7 +439,8 @@
   }
 }
 
-struct GNUNET_ATS_Information
+
+static struct GNUNET_ATS_Information
 env_get_address_type (void *cls,
                      const struct sockaddr *addr,
                      size_t addrlen)
@@ -446,19 +451,22 @@
   return ats;
 }
 
-const struct GNUNET_MessageHeader *
-env_get_our_hello (void)
+
+static const struct GNUNET_MessageHeader *
+env_get_our_hello ()
 {
   return (const struct GNUNET_MessageHeader *) hello;
 }
 
-void env_session_end (void *cls,
-                      const struct GNUNET_PeerIdentity *peer,
-                      struct Session * session)
+
+static void 
+env_session_end (void *cls,
+                const struct GNUNET_PeerIdentity *peer,
+                struct Session * session)
 {
-
 }
 
+
 static void
 setup_plugin_environment ()
 {
@@ -482,6 +490,7 @@
   return GNUNET_OK;
 }
 
+
 /**
  * Runs the test.
  *
@@ -502,33 +511,31 @@
 
   cfg = c;
   /* parse configuration */
-  if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (c,
-                          "TRANSPORT",
-                          "NEIGHBOUR_LIMIT",
-                          &tneigh)) ||
-      (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (c,
-                          "GNUNETD", "HOSTKEY",
-                          &keyfile)))
+  if ( (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (c,
+                                                           "TRANSPORT",
+                                                           "NEIGHBOUR_LIMIT",
+                                                           &tneigh)) ||
+       (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (c,
+                                                             "GNUNETD", 
"HOSTKEY",
+                                                             &keyfile)))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 _("Transport service is lacking key configuration settings.  
Exiting.\n"));
-
     return;
   }
 
-  stats = GNUNET_STATISTICS_create ("transport", cfg);
-  if (NULL == stats)
+  if (NULL == (stats = GNUNET_STATISTICS_create ("transport", cfg)))
   {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  _("Could not create statistics.  Exiting.\n"));
-      end_badly_now ();
-      return;
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+               _("Could not create statistics.  Exiting.\n"));
+    end_badly_now ();
+    return;
   }
 
   max_connect_per_transport = (uint32_t) tneigh;
   my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
   GNUNET_free (keyfile);
-  if (my_private_key == NULL)
+  if (NULL == my_private_key)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 _("Transport service could not access hostkey.  Exiting.\n"));
@@ -638,7 +645,7 @@
 
 
 /**
- * The main function for the transport service.
+ * The main function for the test
  *
  * @param argc number of arguments from the command line
  * @param argv command line arguments
@@ -656,20 +663,19 @@
     "test_plugin_transport",
     "-c",
     "test_plugin_transport_data.conf",
-    "-L", "WARNING",
     NULL
   };
   GNUNET_log_setup ("test-plugin-transport",
                     "WARNING",
                     NULL);
   ok = 1;                       /* set to fail */
-  ret = (GNUNET_OK == GNUNET_PROGRAM_run (5,
-                           argv_prog,
-                           "test-plugin-transport",
-                           "testcase",
-                           options,
-                           &run,
-                           (void *) argv)) ? ok : 1;
+  ret = (GNUNET_OK == GNUNET_PROGRAM_run (3,
+                                         argv_prog,
+                                         "test-plugin-transport",
+                                         "testcase",
+                                         options,
+                                         &run,
+                                         (void *) argv)) ? ok : 1;
   GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-plugin-transport");
   return ret;
 }

Modified: gnunet/src/util/crypto_random.c
===================================================================
--- gnunet/src/util/crypto_random.c     2012-09-17 10:09:32 UTC (rev 23844)
+++ gnunet/src/util/crypto_random.c     2012-09-17 10:45:23 UTC (rev 23845)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other 
contributing authors)
+     (C) 2001, 2002, 2003, 2004, 2005, 2006, 2012 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
@@ -34,6 +34,14 @@
 
 #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", 
syscall)
 
+
+/**
+ * GNUNET_YES if we are using a 'weak' (low-entropy) PRNG.
+ */ 
+static int weak_random;
+
+
+
 /* TODO: ndurner, move this to plibc? */
 /* The code is derived from glibc, obviously */
 #if MINGW
@@ -49,14 +57,18 @@
 #undef RAND_MAX
 #endif
 #define RAND_MAX 0x7fffffff /* Hopefully this is correct */
+
+
 static int32_t glibc_weak_rand32_state = 1;
 
+
 void
 glibc_weak_srand32 (int32_t s)
 {
   glibc_weak_rand32_state = s;
 }
 
+
 int32_t
 glibc_weak_rand32 ()
 {
@@ -74,11 +86,12 @@
  * @return number between 0 and 1.
  */
 static double
-weak_random ()
+get_weak_random ()
 {
   return ((double) RANDOM () / RAND_MAX);
 }
 
+
 /**
  * Seed a weak random generator. Only GNUNET_CRYPTO_QUALITY_WEAK-mode generator
  * can be seeded.
@@ -91,6 +104,7 @@
   SRANDOM (seed);
 }
 
+
 /**
  * Produce a random value.
  *
@@ -134,7 +148,7 @@
     while (ret >= ul);
     return ret % i;
   case GNUNET_CRYPTO_QUALITY_WEAK:
-    ret = i * weak_random ();
+    ret = i * get_weak_random ();
     if (ret >= i)
       ret = i - 1;
     return ret;
@@ -211,7 +225,7 @@
 
     return ret % max;
   case GNUNET_CRYPTO_QUALITY_WEAK:
-    ret = max * weak_random ();
+    ret = max * get_weak_random ();
     if (ret >= max)
       ret = max - 1;
     return ret;
@@ -221,7 +235,20 @@
   return 0;
 }
 
+
 /**
+ * Check if we are using weak random number generation.
+ *
+ * @return GNUNET_YES if weak number generation is on
+ */
+int
+GNUNET_CRYPTO_random_is_weak ()
+{
+  return weak_random;
+}
+
+
+/**
  * This function should only be called in testcases
  * where strong entropy gathering is not desired
  * (for example, for hostkey generation).
@@ -229,6 +256,7 @@
 void
 GNUNET_CRYPTO_random_disable_entropy_gathering ()
 {
+  weak_random = GNUNET_YES;
   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
 }
 
@@ -239,6 +267,7 @@
  */
 static struct GNUNET_OS_Process *genproc;
 
+
 /**
  * Function called by libgcrypt whenever we are
  * blocked gathering entropy.

Modified: gnunet/src/util/crypto_rsa.c
===================================================================
--- gnunet/src/util/crypto_rsa.c        2012-09-17 10:09:32 UTC (rev 23844)
+++ gnunet/src/util/crypto_rsa.c        2012-09-17 10:45:23 UTC (rev 23845)
@@ -629,11 +629,17 @@
     (void) GNUNET_DISK_file_close (fd);
     return NULL;
   }
+  if (0 == fs)
+  {
+    GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd));
+    return NULL;
+  }
   if (fs > UINT16_MAX)
   {
     LOG (GNUNET_ERROR_TYPE_ERROR,
-         _("File `%s' does not contain a valid private key.  Deleting it.\n"),
-         filename);
+         _("File `%s' does not contain a valid private key (too long, %llu 
bytes).  Deleting it.\n"),  
+         filename,
+        (unsigned long long) fs);
     GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd));
     if (0 != UNLINK (filename))    
       LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename);
@@ -648,8 +654,9 @@
       (NULL == (ret = GNUNET_CRYPTO_rsa_decode_key ((char *) enc, len))))
   {
     LOG (GNUNET_ERROR_TYPE_ERROR,
-         _("File `%s' does not contain a valid private key.  Deleting it.\n"),
-         filename);
+         _("File `%s' does not contain a valid private key (failed decode, 
%llu bytes).  Deleting it.\n"),
+         filename,
+        (unsigned long long) fs);
     GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd));
     if (0 != UNLINK (filename))    
       LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename);
@@ -664,6 +671,23 @@
 
 
 /**
+ * Wait for a short time (we're trying to lock a file or want
+ * to give another process a shot at finishing a disk write, etc.).
+ * Sleeps for 100ms (as that should be long enough for virtually all
+ * modern systems to context switch and allow another process to do
+ * some 'real' work).
+ */
+static void
+short_wait ()
+{
+  struct GNUNET_TIME_Relative timeout;
+
+  timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100);
+  GNUNET_NETWORK_socket_select (NULL, NULL, NULL, timeout);
+}
+
+
+/**
  * Create a new private key by reading it from a file.  If the
  * files does not exist, create a new key and write it to the
  * file.  Caller must free return value.  Note that this function
@@ -723,7 +747,7 @@
                                   sizeof (struct 
GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded),
                                   GNUNET_YES))
     {
-      sleep (1);
+      short_wait (1);
       if (0 == ++cnt % 10)
       {
         ec = errno;
@@ -781,7 +805,7 @@
              _
              ("This may be ok if someone is currently generating a 
hostkey.\n"));
       }
-      sleep (1);
+      short_wait (1);
       continue;
     }
     if (GNUNET_YES != GNUNET_DISK_file_test (filename))
@@ -817,7 +841,7 @@
              _
              ("This may be ok if someone is currently generating a 
hostkey.\n"));
       }
-      sleep (2);                /* wait a bit longer! */
+      short_wait (1);                /* wait a bit longer! */
       continue;
     }
     break;
@@ -996,6 +1020,7 @@
 {
   struct GNUNET_CRYPTO_RsaKeyGenerationContext *gc;
   struct GNUNET_CRYPTO_RsaPrivateKey *pk;
+  const char *weak_random;
 
   if (NULL != (pk = try_read_key (filename)))
   {
@@ -1023,13 +1048,18 @@
     GNUNET_free (gc);
     return NULL;
   }
+  weak_random = NULL;
+  if (GNUNET_YES ==
+      GNUNET_CRYPTO_random_is_weak ())
+    weak_random = "-w";
   gc->gnunet_rsa = GNUNET_OS_start_process (GNUNET_NO,
                                            GNUNET_OS_INHERIT_STD_ERR,
                                            NULL, 
                                            gc->gnunet_rsa_out,
                                            "gnunet-rsa",
-                                           "gnunet-rsa",
+                                           "gnunet-rsa",                       
                    
                                            gc->filename,
+                                           weak_random,
                                            NULL);
   if (NULL == gc->gnunet_rsa)
   {

Modified: gnunet/src/util/gnunet-rsa.c
===================================================================
--- gnunet/src/util/gnunet-rsa.c        2012-09-17 10:09:32 UTC (rev 23844)
+++ gnunet/src/util/gnunet-rsa.c        2012-09-17 10:45:23 UTC (rev 23845)
@@ -43,7 +43,12 @@
  */
 static int print_short_identity;
 
+/**
+ * Use weak random number generator for key generation.
+ */
+static int weak_random;
 
+
 /**
  * The private information of an RSA key pair.
  * NOTE: this must match the definition in crypto_ksk.c and crypto_rsa.c!
@@ -104,6 +109,8 @@
     fprintf (stderr, _("No hostkey file specified on command line\n"));
     return;
   }
+  if (0 != weak_random)    
+    GNUNET_CRYPTO_random_disable_entropy_gathering ();  
   pk = GNUNET_CRYPTO_rsa_key_create_from_file (args[0]);
   if (NULL == pk)
     return;
@@ -159,6 +166,9 @@
     { 's', "print-short-identity", NULL,
       gettext_noop ("print the short hash of the public key in ASCII format"),
       0, &GNUNET_GETOPT_set_one, &print_short_identity },
+    { 'w', "weak-random", NULL,
+      gettext_noop ("use insecure, weak random number generator for key 
generation (for testing only)"),
+      0, &GNUNET_GETOPT_set_one, &weak_random },
     GNUNET_GETOPT_OPTION_END
   };
 

Modified: gnunet/src/util/server.c
===================================================================
--- gnunet/src/util/server.c    2012-09-17 10:09:32 UTC (rev 23844)
+++ gnunet/src/util/server.c    2012-09-17 10:45:23 UTC (rev 23845)
@@ -334,43 +334,6 @@
 
 
 /**
- * Add a listen task with the scheduler for this server.
- *
- * @param server handle to our server for which we are adding the listen
- *        socket
- */
-static void
-schedule_listen_task (struct GNUNET_SERVER_Handle *server)
-{
-  struct GNUNET_NETWORK_FDSet *r;
-  unsigned int i;
-
-  if (NULL == server->listen_sockets[0])
-    return; /* nothing to do, no listen sockets! */
-  if (NULL == server->listen_sockets[1])
-  {
-    /* simplified method: no fd set needed; this is then much simpler and
-       much more efficient */
-    server->listen_task =
-      GNUNET_SCHEDULER_add_read_net_with_priority 
(GNUNET_TIME_UNIT_FOREVER_REL,
-                                                  
GNUNET_SCHEDULER_PRIORITY_HIGH,
-                                                  server->listen_sockets[0],
-                                                  &process_listen_socket, 
server);
-    return;
-  }
-  r = GNUNET_NETWORK_fdset_create ();
-  i = 0;
-  while (NULL != server->listen_sockets[i])
-    GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
-  server->listen_task =
-    GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
-                                GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
-                                &process_listen_socket, server);
-  GNUNET_NETWORK_fdset_destroy (r);
-}
-
-
-/**
  * Scheduler says our listen socket is ready.  Process it!
  *
  * @param cls handle to our server for which we are processing the listen
@@ -389,7 +352,7 @@
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
   {
     /* ignore shutdown, someone else will take care of it! */
-    schedule_listen_task (server);
+    GNUNET_SERVER_resume (server);
     return;
   }
   i = 0;
@@ -412,7 +375,7 @@
     i++;
   }
   /* listen for more! */
-  schedule_listen_task (server);
+  GNUNET_SERVER_resume (server);
 }
 
 
@@ -536,7 +499,7 @@
   server->access_cls = access_cls;
   server->require_found = require_found;
   if (NULL != lsocks)
-    schedule_listen_task (server);
+    GNUNET_SERVER_resume (server);
   return server;
 }
 
@@ -671,6 +634,58 @@
 
 
 /**
+ * Suspend accepting connections from the listen socket temporarily.
+ *
+ * @param server server to stop accepting connections.
+ */
+void
+GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server)
+{
+  if (GNUNET_SCHEDULER_NO_TASK != server->listen_task)
+  {
+    GNUNET_SCHEDULER_cancel (server->listen_task);
+    server->listen_task = GNUNET_SCHEDULER_NO_TASK;
+  }
+}
+
+
+/**
+ * Resume accepting connections from the listen socket.
+ *
+ * @param server server to stop accepting connections.
+ */
+void
+GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server)
+{
+  struct GNUNET_NETWORK_FDSet *r;
+  unsigned int i;
+
+  if (NULL == server->listen_sockets[0])
+    return; /* nothing to do, no listen sockets! */
+  if (NULL == server->listen_sockets[1])
+  {
+    /* simplified method: no fd set needed; this is then much simpler and
+       much more efficient */
+    server->listen_task =
+      GNUNET_SCHEDULER_add_read_net_with_priority 
(GNUNET_TIME_UNIT_FOREVER_REL,
+                                                  
GNUNET_SCHEDULER_PRIORITY_HIGH,
+                                                  server->listen_sockets[0],
+                                                  &process_listen_socket, 
server);
+    return;
+  }
+  r = GNUNET_NETWORK_fdset_create ();
+  i = 0;
+  while (NULL != server->listen_sockets[i])
+    GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
+  server->listen_task =
+    GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
+                                GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
+                                &process_listen_socket, server);
+  GNUNET_NETWORK_fdset_destroy (r);
+}
+
+
+/**
  * Stop the listen socket and get ready to shutdown the server
  * once only 'monitor' clients are left.
  *




reply via email to

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