aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-09-17 10:45:23 +0000
committerChristian Grothoff <christian@grothoff.org>2012-09-17 10:45:23 +0000
commit7e065c18499688141eb68513058131a49344cac1 (patch)
treee441b44c8f0db8a4f214775e4945039cc820cf2f
parentb3ad920b6e0107c3da946fe1f2f720955dbac151 (diff)
downloadgnunet-7e065c18499688141eb68513058131a49344cac1.tar.gz
gnunet-7e065c18499688141eb68513058131a49344cac1.zip
fixing #1551/#2503
-rw-r--r--src/core/gnunet-service-core.c86
-rw-r--r--src/core/gnunet-service-core_kx.c23
-rw-r--r--src/core/gnunet-service-core_kx.h3
-rw-r--r--src/fs/fs_uri.c3
-rw-r--r--src/include/gnunet_crypto_lib.h11
-rw-r--r--src/include/gnunet_server_lib.h18
-rw-r--r--src/mesh/gnunet-service-mesh.c154
-rw-r--r--src/nse/gnunet-service-nse.c195
-rw-r--r--src/peerinfo-tool/gnunet-peerinfo.c14
-rw-r--r--src/transport/gnunet-service-transport.c109
-rw-r--r--src/transport/test_plugin_transport.c68
-rw-r--r--src/util/crypto_random.c37
-rw-r--r--src/util/crypto_rsa.c46
-rw-r--r--src/util/gnunet-rsa.c10
-rw-r--r--src/util/server.c95
15 files changed, 576 insertions, 296 deletions
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index 59d938364..f5d01cd27 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -48,21 +48,39 @@ const struct GNUNET_CONFIGURATION_Handle *GSC_cfg;
48 */ 48 */
49struct GNUNET_STATISTICS_Handle *GSC_stats; 49struct GNUNET_STATISTICS_Handle *GSC_stats;
50 50
51/**
52 * Handle to the server of the core service.
53 */
54static struct GNUNET_SERVER_Handle *GSC_server;
55
56/**
57 * Hostkey generation context
58 */
59struct GNUNET_CRYPTO_RsaKeyGenerationContext *GST_keygen;
60
51 61
52/** 62/**
53 * Last task run during shutdown. Disconnects us from 63 * Last task run during shutdown. Disconnects us from
54 * the transport. 64 * the transport.
65 *
66 * @param cls NULL, unused
67 * @param tc scheduler context, unused
55 */ 68 */
56static void 69static void
57cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 70shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
58{ 71{
59 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n"); 72 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n");
73 if (NULL != GST_keygen)
74 {
75 GNUNET_CRYPTO_rsa_key_create_stop (GST_keygen);
76 GST_keygen = NULL;
77 }
60 GSC_CLIENTS_done (); 78 GSC_CLIENTS_done ();
61 GSC_NEIGHBOURS_done (); 79 GSC_NEIGHBOURS_done ();
62 GSC_SESSIONS_done (); 80 GSC_SESSIONS_done ();
63 GSC_KX_done (); 81 GSC_KX_done ();
64 GSC_TYPEMAP_done (); 82 GSC_TYPEMAP_done ();
65 if (GSC_stats != NULL) 83 if (NULL != GSC_stats)
66 { 84 {
67 GNUNET_STATISTICS_destroy (GSC_stats, GNUNET_NO); 85 GNUNET_STATISTICS_destroy (GSC_stats, GNUNET_NO);
68 GSC_stats = NULL; 86 GSC_stats = NULL;
@@ -71,6 +89,42 @@ cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
71} 89}
72 90
73 91
92
93/**
94 * Callback for hostkey read/generation
95 *
96 * @param cls NULL
97 * @param pk the private key
98 * @param emsg error message
99 */
100static void
101key_generation_cb (void *cls,
102 struct GNUNET_CRYPTO_RsaPrivateKey *pk,
103 const char *emsg)
104{
105 GST_keygen = NULL;
106 if (NULL == pk)
107 {
108 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
109 _("Failed to read hostkey: %s\n"),
110 emsg);
111 GNUNET_SCHEDULER_shutdown ();
112 return;
113 }
114 if ((GNUNET_OK != GSC_KX_init (pk)) ||
115 (GNUNET_OK != GSC_NEIGHBOURS_init ()))
116 {
117 GNUNET_SCHEDULER_shutdown ();
118 return;
119 }
120 GSC_SESSIONS_init ();
121 GSC_CLIENTS_init (GSC_server);
122 GNUNET_SERVER_resume (GSC_server);
123 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Core service of `%4s' ready.\n"),
124 GNUNET_i2s (&GSC_my_identity));
125}
126
127
74/** 128/**
75 * Initiate core service. 129 * Initiate core service.
76 * 130 *
@@ -82,24 +136,36 @@ static void
82run (void *cls, struct GNUNET_SERVER_Handle *server, 136run (void *cls, struct GNUNET_SERVER_Handle *server,
83 const struct GNUNET_CONFIGURATION_Handle *c) 137 const struct GNUNET_CONFIGURATION_Handle *c)
84{ 138{
139 char *keyfile;
140
85 GSC_cfg = c; 141 GSC_cfg = c;
142 GSC_server = server;
143 if (GNUNET_OK !=
144 GNUNET_CONFIGURATION_get_value_filename (GSC_cfg, "GNUNETD", "HOSTKEY",
145 &keyfile))
146 {
147 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
148 _
149 ("Core service is lacking HOSTKEY configuration setting. Exiting.\n"));
150 GNUNET_SCHEDULER_shutdown ();
151 return;
152 }
86 GSC_stats = GNUNET_STATISTICS_create ("core", GSC_cfg); 153 GSC_stats = GNUNET_STATISTICS_create ("core", GSC_cfg);
87 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleaning_task, 154 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
88 NULL); 155 NULL);
156 GNUNET_SERVER_suspend (server);
89 GSC_TYPEMAP_init (); 157 GSC_TYPEMAP_init ();
90 if ((GNUNET_OK != GSC_KX_init ()) || (GNUNET_OK != GSC_NEIGHBOURS_init ())) 158 GST_keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, &key_generation_cb, NULL);
159 GNUNET_free (keyfile);
160 if (NULL == GST_keygen)
91 { 161 {
162 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
163 _("Transport service is unable to access hostkey. Exiting.\n"));
92 GNUNET_SCHEDULER_shutdown (); 164 GNUNET_SCHEDULER_shutdown ();
93 return;
94 } 165 }
95 GSC_SESSIONS_init ();
96 GSC_CLIENTS_init (server);
97 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Core service of `%4s' ready.\n"),
98 GNUNET_i2s (&GSC_my_identity));
99} 166}
100 167
101 168
102
103/** 169/**
104 * The main function for the transport service. 170 * The main function for the transport service.
105 * 171 *
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c
index f5bea09e5..755d0c34c 100644
--- a/src/core/gnunet-service-core_kx.c
+++ b/src/core/gnunet-service-core_kx.c
@@ -1686,30 +1686,13 @@ deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m)
1686/** 1686/**
1687 * Initialize KX subsystem. 1687 * Initialize KX subsystem.
1688 * 1688 *
1689 * @param pk private key to use for the peer
1689 * @return GNUNET_OK on success, GNUNET_SYSERR on failure 1690 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
1690 */ 1691 */
1691int 1692int
1692GSC_KX_init () 1693GSC_KX_init (struct GNUNET_CRYPTO_RsaPrivateKey *pk)
1693{ 1694{
1694 char *keyfile; 1695 my_private_key = pk;
1695
1696 if (GNUNET_OK !=
1697 GNUNET_CONFIGURATION_get_value_filename (GSC_cfg, "GNUNETD", "HOSTKEY",
1698 &keyfile))
1699 {
1700 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1701 _
1702 ("Core service is lacking HOSTKEY configuration setting. Exiting.\n"));
1703 return GNUNET_SYSERR;
1704 }
1705 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
1706 GNUNET_free (keyfile);
1707 if (NULL == my_private_key)
1708 {
1709 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1710 _("Core service could not access hostkey. Exiting.\n"));
1711 return GNUNET_SYSERR;
1712 }
1713 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key); 1696 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
1714 GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key), 1697 GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
1715 &GSC_my_identity.hashPubKey); 1698 &GSC_my_identity.hashPubKey);
diff --git a/src/core/gnunet-service-core_kx.h b/src/core/gnunet-service-core_kx.h
index 5ecd2c17f..fcb561e01 100644
--- a/src/core/gnunet-service-core_kx.h
+++ b/src/core/gnunet-service-core_kx.h
@@ -121,10 +121,11 @@ GSC_KX_stop (struct GSC_KeyExchangeInfo *kx);
121/** 121/**
122 * Initialize KX subsystem. 122 * Initialize KX subsystem.
123 * 123 *
124 * @param pk private key to use for the peer
124 * @return GNUNET_OK on success, GNUNET_SYSERR on failure 125 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
125 */ 126 */
126int 127int
127GSC_KX_init (void); 128GSC_KX_init (struct GNUNET_CRYPTO_RsaPrivateKey *pk);
128 129
129 130
130/** 131/**
diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c
index ad21692c9..0f4168918 100644
--- a/src/fs/fs_uri.c
+++ b/src/fs/fs_uri.c
@@ -903,8 +903,7 @@ GNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *baseUri,
903 _("Lacking key configuration settings.\n")); 903 _("Lacking key configuration settings.\n"));
904 return NULL; 904 return NULL;
905 } 905 }
906 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); 906 if (NULL == (my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile)))
907 if (my_private_key == NULL)
908 { 907 {
909 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 908 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
910 _("Could not access hostkey file `%s'.\n"), keyfile); 909 _("Could not access hostkey file `%s'.\n"), keyfile);
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index b73d26d1e..710ef3179 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -1085,6 +1085,17 @@ void
1085GNUNET_CRYPTO_random_disable_entropy_gathering (void); 1085GNUNET_CRYPTO_random_disable_entropy_gathering (void);
1086 1086
1087 1087
1088/**
1089 * Check if we are using weak random number generation.
1090 *
1091 * @return GNUNET_YES if weak number generation is on
1092 * (thus will return YES if 'GNUNET_CRYPTO_random_disable_entropy_gathering'
1093 * was called previously).
1094 */
1095int
1096GNUNET_CRYPTO_random_is_weak (void);
1097
1098
1088#if 0 /* keep Emacsens' auto-indent happy */ 1099#if 0 /* keep Emacsens' auto-indent happy */
1089{ 1100{
1090#endif 1101#endif
diff --git a/src/include/gnunet_server_lib.h b/src/include/gnunet_server_lib.h
index 73fe8000e..aaf47aca5 100644
--- a/src/include/gnunet_server_lib.h
+++ b/src/include/gnunet_server_lib.h
@@ -155,6 +155,24 @@ GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls,
155 155
156 156
157/** 157/**
158 * Suspend accepting connections from the listen socket temporarily.
159 *
160 * @param server server to stop accepting connections.
161 */
162void
163GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server);
164
165
166/**
167 * Resume accepting connections from the listen socket.
168 *
169 * @param server server to stop accepting connections.
170 */
171void
172GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server);
173
174
175/**
158 * Stop the listen socket and get ready to shutdown the server 176 * Stop the listen socket and get ready to shutdown the server
159 * once only 'monitor' clients are left. 177 * once only 'monitor' clients are left.
160 * 178 *
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index 2ce30c82f..e40a3de96 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2001 - 2011 Christian Grothoff (and other contributing authors) 3 (C) 2001-2012 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -816,6 +816,12 @@ static long long unsigned int dht_replication_level;
816static long long unsigned int max_tunnels; 816static long long unsigned int max_tunnels;
817static long long unsigned int max_msgs_queue; 817static long long unsigned int max_msgs_queue;
818 818
819
820/**
821 * Hostkey generation context
822 */
823static struct GNUNET_CRYPTO_RsaKeyGenerationContext *keygen;
824
819/** 825/**
820 * DLL with all the clients, head. 826 * DLL with all the clients, head.
821 */ 827 */
@@ -7684,6 +7690,7 @@ shutdown_peer (void *cls, const struct GNUNET_HashCode * key, void *value)
7684 return GNUNET_YES; 7690 return GNUNET_YES;
7685} 7691}
7686 7692
7693
7687/** 7694/**
7688 * Task run during shutdown. 7695 * Task run during shutdown.
7689 * 7696 *
@@ -7700,6 +7707,11 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
7700 GNUNET_CORE_disconnect (core_handle); 7707 GNUNET_CORE_disconnect (core_handle);
7701 core_handle = NULL; 7708 core_handle = NULL;
7702 } 7709 }
7710 if (NULL != keygen)
7711 {
7712 GNUNET_CRYPTO_rsa_key_create_stop (keygen);
7713 keygen = NULL;
7714 }
7703 GNUNET_CONTAINER_multihashmap_iterate (tunnels, &shutdown_tunnel, NULL); 7715 GNUNET_CONTAINER_multihashmap_iterate (tunnels, &shutdown_tunnel, NULL);
7704 GNUNET_CONTAINER_multihashmap_iterate (peers, &shutdown_peer, NULL); 7716 GNUNET_CONTAINER_multihashmap_iterate (peers, &shutdown_peer, NULL);
7705 if (dht_handle != NULL) 7717 if (dht_handle != NULL)
@@ -7720,6 +7732,76 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
7720 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n"); 7732 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n");
7721} 7733}
7722 7734
7735
7736/**
7737 * Callback for hostkey read/generation
7738 *
7739 * @param cls NULL
7740 * @param pk the private key
7741 * @param emsg error message
7742 */
7743static void
7744key_generation_cb (void *cls,
7745 struct GNUNET_CRYPTO_RsaPrivateKey *pk,
7746 const char *emsg)
7747{
7748 struct MeshPeerInfo *peer;
7749 struct MeshPeerPath *p;
7750
7751 keygen = NULL;
7752 if (NULL == pk)
7753 {
7754 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
7755 _("Mesh service could not access hostkey. Exiting.\n"));
7756 GNUNET_SCHEDULER_shutdown ();
7757 return;
7758 }
7759 my_private_key = pk;
7760 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
7761 GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
7762 &my_full_id.hashPubKey);
7763 myid = GNUNET_PEER_intern (&my_full_id);
7764 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
7765 "Mesh for peer [%s] starting\n",
7766 GNUNET_i2s(&my_full_id));
7767
7768// transport_handle = GNUNET_TRANSPORT_connect(c,
7769// &my_full_id,
7770// NULL,
7771// NULL,
7772// NULL,
7773// NULL);
7774
7775
7776
7777 next_tid = 0;
7778 next_local_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
7779
7780
7781 GNUNET_SERVER_add_handlers (server_handle, client_handlers);
7782 nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
7783 GNUNET_SERVER_disconnect_notify (server_handle,
7784 &handle_local_client_disconnect, NULL);
7785
7786
7787 clients = NULL;
7788 clients_tail = NULL;
7789 next_client_id = 0;
7790
7791 announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
7792 announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
7793
7794 /* Create a peer_info for the local peer */
7795 peer = peer_info_get (&my_full_id);
7796 p = path_new (1);
7797 p->peers[0] = myid;
7798 GNUNET_PEER_change_rc (myid, 1);
7799 peer_info_add_path (peer, p, GNUNET_YES);
7800 GNUNET_SERVER_resume (server_handle);
7801 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh service running\n");
7802}
7803
7804
7723/** 7805/**
7724 * Process mesh requests. 7806 * Process mesh requests.
7725 * 7807 *
@@ -7731,8 +7813,6 @@ static void
7731run (void *cls, struct GNUNET_SERVER_Handle *server, 7813run (void *cls, struct GNUNET_SERVER_Handle *server,
7732 const struct GNUNET_CONFIGURATION_Handle *c) 7814 const struct GNUNET_CONFIGURATION_Handle *c)
7733{ 7815{
7734 struct MeshPeerInfo *peer;
7735 struct MeshPeerPath *p;
7736 char *keyfile; 7816 char *keyfile;
7737 7817
7738 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n"); 7818 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n");
@@ -7873,76 +7953,28 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
7873 dht_replication_level = 10; 7953 dht_replication_level = 10;
7874 } 7954 }
7875 7955
7876
7877 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
7878 GNUNET_free (keyfile);
7879 if (my_private_key == NULL)
7880 {
7881 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
7882 _("Mesh service could not access hostkey. Exiting.\n"));
7883 GNUNET_SCHEDULER_shutdown ();
7884 return;
7885 }
7886 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
7887 GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
7888 &my_full_id.hashPubKey);
7889 myid = GNUNET_PEER_intern (&my_full_id);
7890 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
7891 "Mesh for peer [%s] starting\n",
7892 GNUNET_i2s(&my_full_id));
7893
7894// transport_handle = GNUNET_TRANSPORT_connect(c,
7895// &my_full_id,
7896// NULL,
7897// NULL,
7898// NULL,
7899// NULL);
7900
7901 dht_handle = GNUNET_DHT_connect (c, 64);
7902 if (dht_handle == NULL)
7903 {
7904 GNUNET_break (0);
7905 }
7906
7907 stats = GNUNET_STATISTICS_create ("mesh", c);
7908
7909
7910 next_tid = 0;
7911 next_local_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
7912
7913 tunnels = GNUNET_CONTAINER_multihashmap_create (32); 7956 tunnels = GNUNET_CONTAINER_multihashmap_create (32);
7914 incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32); 7957 incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32);
7915 peers = GNUNET_CONTAINER_multihashmap_create (32); 7958 peers = GNUNET_CONTAINER_multihashmap_create (32);
7916 applications = GNUNET_CONTAINER_multihashmap_create (32); 7959 applications = GNUNET_CONTAINER_multihashmap_create (32);
7917 types = GNUNET_CONTAINER_multihashmap_create (32); 7960 types = GNUNET_CONTAINER_multihashmap_create (32);
7918 7961
7919 GNUNET_SERVER_add_handlers (server_handle, client_handlers); 7962 dht_handle = GNUNET_DHT_connect (c, 64);
7920 nc = GNUNET_SERVER_notification_context_create (server_handle, 1); 7963 if (NULL == dht_handle)
7921 GNUNET_SERVER_disconnect_notify (server_handle, 7964 {
7922 &handle_local_client_disconnect, NULL); 7965 GNUNET_break (0);
7923 7966 }
7924 7967 stats = GNUNET_STATISTICS_create ("mesh", c);
7925 clients = NULL;
7926 clients_tail = NULL;
7927 next_client_id = 0;
7928
7929 announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
7930 announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
7931
7932 /* Create a peer_info for the local peer */
7933 peer = peer_info_get (&my_full_id);
7934 p = path_new (1);
7935 p->peers[0] = myid;
7936 GNUNET_PEER_change_rc (myid, 1);
7937 peer_info_add_path (peer, p, GNUNET_YES);
7938 7968
7969 GNUNET_SERVER_suspend (server_handle);
7939 /* Scheduled the task to clean up when shutdown is called */ 7970 /* Scheduled the task to clean up when shutdown is called */
7940 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, 7971 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
7941 NULL); 7972 NULL);
7942 7973 keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, &key_generation_cb, NULL);
7943 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "end of run()\n"); 7974 GNUNET_free (keyfile);
7944} 7975}
7945 7976
7977
7946/** 7978/**
7947 * The main function for the mesh service. 7979 * The main function for the mesh service.
7948 * 7980 *
diff --git a/src/nse/gnunet-service-nse.c b/src/nse/gnunet-service-nse.c
index 3031e6853..435f22774 100644
--- a/src/nse/gnunet-service-nse.c
+++ b/src/nse/gnunet-service-nse.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors) 3 (C) 2009, 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -304,6 +304,16 @@ static struct GNUNET_PeerIdentity my_identity;
304 */ 304 */
305static uint64_t my_proof; 305static uint64_t my_proof;
306 306
307/**
308 * Handle to this serivce's server.
309 */
310static struct GNUNET_SERVER_Handle *srv;
311
312/**
313 * Hostkey generation context
314 */
315static struct GNUNET_CRYPTO_RsaKeyGenerationContext *keygen;
316
307 317
308/** 318/**
309 * Initialize a message to clients with the current network 319 * Initialize a message to clients with the current network
@@ -576,7 +586,7 @@ transmit_ready (void *cls, size_t size, void *buf)
576 GNUNET_SCHEDULER_add_delayed (get_transmit_delay (0), &transmit_task_cb, 586 GNUNET_SCHEDULER_add_delayed (get_transmit_delay (0), &transmit_task_cb,
577 peer_entry); 587 peer_entry);
578 } 588 }
579 if ((ntohl (size_estimate_messages[idx].hop_count) == 0) && 589 if ((0 == ntohl (size_estimate_messages[idx].hop_count)) &&
580 (GNUNET_SCHEDULER_NO_TASK != proof_task)) 590 (GNUNET_SCHEDULER_NO_TASK != proof_task))
581 { 591 {
582 GNUNET_STATISTICS_update (stats, 592 GNUNET_STATISTICS_update (stats,
@@ -584,7 +594,7 @@ transmit_ready (void *cls, size_t size, void *buf)
584 1, GNUNET_NO); 594 1, GNUNET_NO);
585 return 0; 595 return 0;
586 } 596 }
587 if (ntohs (size_estimate_messages[idx].header.size) == 0) 597 if (0 == ntohs (size_estimate_messages[idx].header.size))
588 { 598 {
589 GNUNET_STATISTICS_update (stats, 599 GNUNET_STATISTICS_update (stats,
590 "# flood messages not generated (lack of history)", 600 "# flood messages not generated (lack of history)",
@@ -661,7 +671,8 @@ update_network_size_estimate ()
661 * @param ts timestamp to use 671 * @param ts timestamp to use
662 */ 672 */
663static void 673static void
664setup_flood_message (unsigned int slot, struct GNUNET_TIME_Absolute ts) 674setup_flood_message (unsigned int slot,
675 struct GNUNET_TIME_Absolute ts)
665{ 676{
666 struct GNUNET_NSE_FloodMessage *fm; 677 struct GNUNET_NSE_FloodMessage *fm;
667 uint32_t matching_bits; 678 uint32_t matching_bits;
@@ -699,7 +710,9 @@ setup_flood_message (unsigned int slot, struct GNUNET_TIME_Absolute ts)
699 * @return GNUNET_OK (continue to iterate) 710 * @return GNUNET_OK (continue to iterate)
700 */ 711 */
701static int 712static int
702schedule_current_round (void *cls, const struct GNUNET_HashCode * key, void *value) 713schedule_current_round (void *cls,
714 const struct GNUNET_HashCode * key,
715 void *value)
703{ 716{
704 struct NSEPeerEntry *peer_entry = value; 717 struct NSEPeerEntry *peer_entry = value;
705 struct GNUNET_TIME_Relative delay; 718 struct GNUNET_TIME_Relative delay;
@@ -958,7 +971,7 @@ update_flood_times (void *cls, const struct GNUNET_HashCode * key, void *value)
958 struct NSEPeerEntry *peer_entry = value; 971 struct NSEPeerEntry *peer_entry = value;
959 struct GNUNET_TIME_Relative delay; 972 struct GNUNET_TIME_Relative delay;
960 973
961 if (peer_entry->th != NULL) 974 if (NULL != peer_entry->th)
962 return GNUNET_OK; /* already active */ 975 return GNUNET_OK; /* already active */
963 if (peer_entry == exclude) 976 if (peer_entry == exclude)
964 return GNUNET_OK; /* trigger of the update */ 977 return GNUNET_OK; /* trigger of the update */
@@ -966,14 +979,14 @@ update_flood_times (void *cls, const struct GNUNET_HashCode * key, void *value)
966 { 979 {
967 /* still stuck in previous round, no point to update, check that 980 /* still stuck in previous round, no point to update, check that
968 * we are active here though... */ 981 * we are active here though... */
969 if (GNUNET_SCHEDULER_NO_TASK == peer_entry->transmit_task && 982 if ( (GNUNET_SCHEDULER_NO_TASK == peer_entry->transmit_task) &&
970 NULL == peer_entry->th) 983 (NULL == peer_entry->th) )
971 { 984 {
972 GNUNET_break (0); 985 GNUNET_break (0);
973 } 986 }
974 return GNUNET_OK; 987 return GNUNET_OK;
975 } 988 }
976 if (peer_entry->transmit_task != GNUNET_SCHEDULER_NO_TASK) 989 if (GNUNET_SCHEDULER_NO_TASK != peer_entry->transmit_task)
977 { 990 {
978 GNUNET_SCHEDULER_cancel (peer_entry->transmit_task); 991 GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
979 peer_entry->transmit_task = GNUNET_SCHEDULER_NO_TASK; 992 peer_entry->transmit_task = GNUNET_SCHEDULER_NO_TASK;
@@ -1099,7 +1112,7 @@ handle_p2p_size_estimate (void *cls, const struct GNUNET_PeerIdentity *peer,
1099 GNUNET_SCHEDULER_cancel (peer_entry->transmit_task); 1112 GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
1100 peer_entry->transmit_task = GNUNET_SCHEDULER_NO_TASK; 1113 peer_entry->transmit_task = GNUNET_SCHEDULER_NO_TASK;
1101 } 1114 }
1102 if (peer_entry->th != NULL) 1115 if (NULL != peer_entry->th)
1103 { 1116 {
1104 GNUNET_CORE_notify_transmit_ready_cancel (peer_entry->th); 1117 GNUNET_CORE_notify_transmit_ready_cancel (peer_entry->th);
1105 peer_entry->th = NULL; 1118 peer_entry->th = NULL;
@@ -1228,7 +1241,7 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
1228 GNUNET_SCHEDULER_cancel (pos->transmit_task); 1241 GNUNET_SCHEDULER_cancel (pos->transmit_task);
1229 pos->transmit_task = GNUNET_SCHEDULER_NO_TASK; 1242 pos->transmit_task = GNUNET_SCHEDULER_NO_TASK;
1230 } 1243 }
1231 if (pos->th != NULL) 1244 if (NULL != pos->th)
1232 { 1245 {
1233 GNUNET_CORE_notify_transmit_ready_cancel (pos->th); 1246 GNUNET_CORE_notify_transmit_ready_cancel (pos->th);
1234 pos->th = NULL; 1247 pos->th = NULL;
@@ -1247,44 +1260,49 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
1247static void 1260static void
1248shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 1261shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1249{ 1262{
1250 if (flood_task != GNUNET_SCHEDULER_NO_TASK) 1263 if (GNUNET_SCHEDULER_NO_TASK != flood_task)
1251 { 1264 {
1252 GNUNET_SCHEDULER_cancel (flood_task); 1265 GNUNET_SCHEDULER_cancel (flood_task);
1253 flood_task = GNUNET_SCHEDULER_NO_TASK; 1266 flood_task = GNUNET_SCHEDULER_NO_TASK;
1254 } 1267 }
1255 if (proof_task != GNUNET_SCHEDULER_NO_TASK) 1268 if (GNUNET_SCHEDULER_NO_TASK != proof_task)
1256 { 1269 {
1257 GNUNET_SCHEDULER_cancel (proof_task); 1270 GNUNET_SCHEDULER_cancel (proof_task);
1258 proof_task = GNUNET_SCHEDULER_NO_TASK; 1271 proof_task = GNUNET_SCHEDULER_NO_TASK;
1259 write_proof (); /* remember progress */ 1272 write_proof (); /* remember progress */
1260 } 1273 }
1261 if (nc != NULL) 1274 if (NULL != keygen)
1275 {
1276 GNUNET_CRYPTO_rsa_key_create_stop (keygen);
1277 keygen = NULL;
1278 }
1279 if (NULL != nc)
1262 { 1280 {
1263 GNUNET_SERVER_notification_context_destroy (nc); 1281 GNUNET_SERVER_notification_context_destroy (nc);
1264 nc = NULL; 1282 nc = NULL;
1265 } 1283 }
1266 if (coreAPI != NULL) 1284 if (NULL != coreAPI)
1267 { 1285 {
1268 GNUNET_CORE_disconnect (coreAPI); 1286 GNUNET_CORE_disconnect (coreAPI);
1269 coreAPI = NULL; 1287 coreAPI = NULL;
1270 } 1288 }
1271 if (stats != NULL) 1289 if (NULL != stats)
1272 { 1290 {
1273 GNUNET_STATISTICS_destroy (stats, GNUNET_NO); 1291 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
1274 stats = NULL; 1292 stats = NULL;
1275 } 1293 }
1276 if (peers != NULL) 1294 if (NULL != peers)
1277 { 1295 {
1278 GNUNET_CONTAINER_multihashmap_destroy (peers); 1296 GNUNET_CONTAINER_multihashmap_destroy (peers);
1279 peers = NULL; 1297 peers = NULL;
1280 } 1298 }
1281 if (my_private_key != NULL) 1299 if (NULL != my_private_key)
1282 { 1300 {
1283 GNUNET_CRYPTO_rsa_key_free (my_private_key); 1301 GNUNET_CRYPTO_rsa_key_free (my_private_key);
1284 my_private_key = NULL; 1302 my_private_key = NULL;
1285 } 1303 }
1286#if ENABLE_HISTOGRAM 1304#if ENABLE_HISTOGRAM
1287 if (wh != NULL) 1305 if (NULL != wh)
1288 { 1306 {
1289 GNUNET_break (GNUNET_OK == GNUNET_BIO_write_close (wh)); 1307 GNUNET_break (GNUNET_OK == GNUNET_BIO_write_close (wh));
1290 wh = NULL; 1308 wh = NULL;
@@ -1341,19 +1359,17 @@ core_init (void *cls, struct GNUNET_CORE_Handle *server,
1341 1359
1342 1360
1343/** 1361/**
1344 * Handle network size estimate clients. 1362 * Callback for hostkey read/generation
1345 * 1363 *
1346 * @param cls closure 1364 * @param cls NULL
1347 * @param server the initialized server 1365 * @param pk the private key
1348 * @param c configuration to use 1366 * @param emsg error message
1349 */ 1367 */
1350static void 1368static void
1351run (void *cls, struct GNUNET_SERVER_Handle *server, 1369key_generation_cb (void *cls,
1352 const struct GNUNET_CONFIGURATION_Handle *c) 1370 struct GNUNET_CRYPTO_RsaPrivateKey *pk,
1371 const char *emsg)
1353{ 1372{
1354 char *keyfile;
1355 char *proof;
1356
1357 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 1373 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
1358 {&handle_start_message, NULL, GNUNET_MESSAGE_TYPE_NSE_START, 1374 {&handle_start_message, NULL, GNUNET_MESSAGE_TYPE_NSE_START,
1359 sizeof (struct GNUNET_MessageHeader)}, 1375 sizeof (struct GNUNET_MessageHeader)},
@@ -1364,52 +1380,18 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1364 sizeof (struct GNUNET_NSE_FloodMessage)}, 1380 sizeof (struct GNUNET_NSE_FloodMessage)},
1365 {NULL, 0, 0} 1381 {NULL, 0, 0}
1366 }; 1382 };
1367 cfg = c; 1383 char *proof;
1368
1369 if ((GNUNET_OK !=
1370 GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "INTERVAL",
1371 &gnunet_nse_interval)) ||
1372 (GNUNET_OK !=
1373 GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "WORKDELAY",
1374 &proof_find_delay)) ||
1375 (GNUNET_OK !=
1376 GNUNET_CONFIGURATION_get_value_number (cfg, "NSE", "WORKBITS",
1377 &nse_work_required)))
1378 {
1379 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1380 _
1381 ("NSE service is lacking key configuration settings. Exiting.\n"));
1382 GNUNET_SCHEDULER_shutdown ();
1383 return;
1384 }
1385 if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8)
1386 {
1387 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1388 _("Invalid work requirement for NSE service. Exiting.\n"));
1389 GNUNET_SCHEDULER_shutdown ();
1390 return;
1391 }
1392
1393 1384
1394 if (GNUNET_OK != 1385 keygen = NULL;
1395 GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", "HOSTKEY", 1386 if (NULL == pk)
1396 &keyfile))
1397 {
1398 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1399 _
1400 ("NSE service is lacking key configuration settings. Exiting.\n"));
1401 GNUNET_SCHEDULER_shutdown ();
1402 return;
1403 }
1404 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
1405 GNUNET_free (keyfile);
1406 if (my_private_key == NULL)
1407 { 1387 {
1408 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1388 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1409 _("NSE service could not access hostkey. Exiting.\n")); 1389 _("NSE service could not access hostkey: %s\n"),
1390 emsg);
1410 GNUNET_SCHEDULER_shutdown (); 1391 GNUNET_SCHEDULER_shutdown ();
1411 return; 1392 return;
1412 } 1393 }
1394 my_private_key = pk;
1413 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key); 1395 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
1414 GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key), 1396 GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
1415 &my_identity.hashPubKey); 1397 &my_identity.hashPubKey);
@@ -1419,11 +1401,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1419 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1401 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1420 _ 1402 _
1421 ("NSE service is lacking key configuration settings. Exiting.\n")); 1403 ("NSE service is lacking key configuration settings. Exiting.\n"));
1422 if (my_private_key != NULL) 1404 GNUNET_CRYPTO_rsa_key_free (my_private_key);
1423 { 1405 my_private_key = NULL;
1424 GNUNET_CRYPTO_rsa_key_free (my_private_key);
1425 my_private_key = NULL;
1426 }
1427 GNUNET_SCHEDULER_shutdown (); 1406 GNUNET_SCHEDULER_shutdown ();
1428 return; 1407 return;
1429 } 1408 }
@@ -1437,8 +1416,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1437 &find_proof, NULL); 1416 &find_proof, NULL);
1438 1417
1439 peers = GNUNET_CONTAINER_multihashmap_create (128); 1418 peers = GNUNET_CONTAINER_multihashmap_create (128);
1440 GNUNET_SERVER_add_handlers (server, handlers); 1419 GNUNET_SERVER_add_handlers (srv, handlers);
1441 nc = GNUNET_SERVER_notification_context_create (server, 1); 1420 nc = GNUNET_SERVER_notification_context_create (srv, 1);
1442 /* Connect to core service and register core handlers */ 1421 /* Connect to core service and register core handlers */
1443 coreAPI = GNUNET_CORE_connect (cfg, /* Main configuration */ 1422 coreAPI = GNUNET_CORE_connect (cfg, /* Main configuration */
1444 NULL, /* Closure passed to functions */ 1423 NULL, /* Closure passed to functions */
@@ -1450,8 +1429,11 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1450 NULL, /* Don't want notified about all outbound messages */ 1429 NULL, /* Don't want notified about all outbound messages */
1451 GNUNET_NO, /* For header only outbound notification */ 1430 GNUNET_NO, /* For header only outbound notification */
1452 core_handlers); /* Register these handlers */ 1431 core_handlers); /* Register these handlers */
1453 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, 1432 if (NULL == coreAPI)
1454 NULL); 1433 {
1434 GNUNET_SCHEDULER_shutdown ();
1435 return;
1436 }
1455#if ENABLE_HISTOGRAM 1437#if ENABLE_HISTOGRAM
1456 if (GNUNET_OK == 1438 if (GNUNET_OK ==
1457 GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "HISTOGRAM", &proof)) 1439 GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "HISTOGRAM", &proof))
@@ -1460,17 +1442,70 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1460 GNUNET_free (proof); 1442 GNUNET_free (proof);
1461 } 1443 }
1462#endif 1444#endif
1463 if (coreAPI == NULL) 1445 stats = GNUNET_STATISTICS_create ("nse", cfg);
1446 GNUNET_SERVER_resume (srv);
1447}
1448
1449
1450/**
1451 * Handle network size estimate clients.
1452 *
1453 * @param cls closure
1454 * @param server the initialized server
1455 * @param c configuration to use
1456 */
1457static void
1458run (void *cls,
1459 struct GNUNET_SERVER_Handle *server,
1460 const struct GNUNET_CONFIGURATION_Handle *c)
1461{
1462 char *keyfile;
1463
1464 cfg = c;
1465 srv = server;
1466 if ((GNUNET_OK !=
1467 GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "INTERVAL",
1468 &gnunet_nse_interval)) ||
1469 (GNUNET_OK !=
1470 GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "WORKDELAY",
1471 &proof_find_delay)) ||
1472 (GNUNET_OK !=
1473 GNUNET_CONFIGURATION_get_value_number (cfg, "NSE", "WORKBITS",
1474 &nse_work_required)))
1464 { 1475 {
1476 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1477 _
1478 ("NSE service is lacking key configuration settings. Exiting.\n"));
1465 GNUNET_SCHEDULER_shutdown (); 1479 GNUNET_SCHEDULER_shutdown ();
1466 return; 1480 return;
1467 } 1481 }
1468 stats = GNUNET_STATISTICS_create ("nse", cfg); 1482 if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8)
1483 {
1484 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1485 _("Invalid work requirement for NSE service. Exiting.\n"));
1486 GNUNET_SCHEDULER_shutdown ();
1487 return;
1488 }
1489 if (GNUNET_OK !=
1490 GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", "HOSTKEY",
1491 &keyfile))
1492 {
1493 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1494 _
1495 ("NSE service is lacking key configuration settings. Exiting.\n"));
1496 GNUNET_SCHEDULER_shutdown ();
1497 return;
1498 }
1499 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
1500 NULL);
1501 GNUNET_SERVER_suspend (srv);
1502 keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, &key_generation_cb, NULL);
1503 GNUNET_free (keyfile);
1469} 1504}
1470 1505
1471 1506
1472/** 1507/**
1473 * The main function for the statistics service. 1508 * The main function for the network size estimation service.
1474 * 1509 *
1475 * @param argc number of arguments from the command line 1510 * @param argc number of arguments from the command line
1476 * @param argv command line arguments 1511 * @param argv command line arguments
diff --git a/src/peerinfo-tool/gnunet-peerinfo.c b/src/peerinfo-tool/gnunet-peerinfo.c
index d3637af44..ddadcddd2 100644
--- a/src/peerinfo-tool/gnunet-peerinfo.c
+++ b/src/peerinfo-tool/gnunet-peerinfo.c
@@ -394,10 +394,10 @@ print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer,
394 struct GNUNET_CRYPTO_HashAsciiEncoded enc; 394 struct GNUNET_CRYPTO_HashAsciiEncoded enc;
395 struct PrintContext *pc; 395 struct PrintContext *pc;
396 396
397 if (peer == NULL) 397 if (NULL == peer)
398 { 398 {
399 pic = NULL; /* end of iteration */ 399 pic = NULL; /* end of iteration */
400 if (err_msg != NULL) 400 if (NULL != err_msg)
401 { 401 {
402 FPRINTF (stderr, 402 FPRINTF (stderr,
403 _("Error in communication with PEERINFO service: %s\n"), 403 _("Error in communication with PEERINFO service: %s\n"),
@@ -812,13 +812,14 @@ run (void *cls, char *const *args, const char *cfgfile,
812 char *fn; 812 char *fn;
813 813
814 cfg = c; 814 cfg = c;
815 if (args[0] != NULL) 815 if (NULL != args[0])
816 { 816 {
817 FPRINTF (stderr, _("Invalid command line argument `%s'\n"), args[0]); 817 FPRINTF (stderr,
818 _("Invalid command line argument `%s'\n"),
819 args[0]);
818 return; 820 return;
819 } 821 }
820 peerinfo = GNUNET_PEERINFO_connect (cfg); 822 if (NULL == (peerinfo = GNUNET_PEERINFO_connect (cfg)))
821 if (peerinfo == NULL)
822 { 823 {
823 FPRINTF (stderr, "%s", _("Could not access PEERINFO service. Exiting.\n")); 824 FPRINTF (stderr, "%s", _("Could not access PEERINFO service. Exiting.\n"));
824 return; 825 return;
@@ -834,7 +835,6 @@ run (void *cls, char *const *args, const char *cfgfile,
834 "GNUNETD", "HOSTKEYFILE"); 835 "GNUNETD", "HOSTKEYFILE");
835 return; 836 return;
836 } 837 }
837
838 if (NULL == (priv = GNUNET_CRYPTO_rsa_key_create_from_file (fn))) 838 if (NULL == (priv = GNUNET_CRYPTO_rsa_key_create_from_file (fn)))
839 { 839 {
840 FPRINTF (stderr, _("Loading hostkey from `%s' failed.\n"), fn); 840 FPRINTF (stderr, _("Loading hostkey from `%s' failed.\n"), fn);
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 677d0033c..f9a4c7b9e 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -62,6 +62,16 @@ struct GNUNET_PeerIdentity GST_my_identity;
62struct GNUNET_PEERINFO_Handle *GST_peerinfo; 62struct GNUNET_PEERINFO_Handle *GST_peerinfo;
63 63
64/** 64/**
65 * Hostkey generation context
66 */
67struct GNUNET_CRYPTO_RsaKeyGenerationContext *GST_keygen;
68
69/**
70 * Handle to our service's server.
71 */
72static struct GNUNET_SERVER_Handle *GST_server;
73
74/**
65 * Our public key. 75 * Our public key.
66 */ 76 */
67struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded GST_my_public_key; 77struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded GST_my_public_key;
@@ -271,7 +281,7 @@ plugin_env_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer,
271 break; 281 break;
272 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK: 282 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK:
273 GST_neighbours_handle_session_ack (message, peer, &address, session, ats, 283 GST_neighbours_handle_session_ack (message, peer, &address, session, ats,
274 ats_count); 284 ats_count);
275 break; 285 break;
276 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT: 286 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT:
277 GST_neighbours_handle_disconnect_message (peer, message); 287 GST_neighbours_handle_disconnect_message (peer, message);
@@ -539,6 +549,11 @@ neighbours_address_notification (void *cls,
539static void 549static void
540shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 550shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
541{ 551{
552 if (NULL != GST_keygen)
553 {
554 GNUNET_CRYPTO_rsa_key_create_stop (GST_keygen);
555 GST_keygen = NULL;
556 }
542 GST_neighbours_stop (); 557 GST_neighbours_stop ();
543 GST_validation_stop (); 558 GST_validation_stop ();
544 GST_plugins_unload (); 559 GST_plugins_unload ();
@@ -549,17 +564,17 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
549 GST_blacklist_stop (); 564 GST_blacklist_stop ();
550 GST_hello_stop (); 565 GST_hello_stop ();
551 566
552 if (GST_peerinfo != NULL) 567 if (NULL != GST_peerinfo)
553 { 568 {
554 GNUNET_PEERINFO_disconnect (GST_peerinfo); 569 GNUNET_PEERINFO_disconnect (GST_peerinfo);
555 GST_peerinfo = NULL; 570 GST_peerinfo = NULL;
556 } 571 }
557 if (GST_stats != NULL) 572 if (NULL != GST_stats)
558 { 573 {
559 GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO); 574 GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO);
560 GST_stats = NULL; 575 GST_stats = NULL;
561 } 576 }
562 if (GST_my_private_key != NULL) 577 if (NULL != GST_my_private_key)
563 { 578 {
564 GNUNET_CRYPTO_rsa_key_free (GST_my_private_key); 579 GNUNET_CRYPTO_rsa_key_free (GST_my_private_key);
565 GST_my_private_key = NULL; 580 GST_my_private_key = NULL;
@@ -568,41 +583,32 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
568 583
569 584
570/** 585/**
571 * Initiate transport service. 586 * Callback for hostkey read/generation
572 * 587 *
573 * @param cls closure 588 * @param cls NULL
574 * @param server the initialized server 589 * @param pk the private key
575 * @param c configuration to use 590 * @param emsg error message
576 */ 591 */
577static void 592static void
578run (void *cls, struct GNUNET_SERVER_Handle *server, 593key_generation_cb (void *cls,
579 const struct GNUNET_CONFIGURATION_Handle *c) 594 struct GNUNET_CRYPTO_RsaPrivateKey *pk,
595 const char *emsg)
580{ 596{
581 char *keyfile;
582 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded tmp; 597 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded tmp;
583 /* setup globals */ 598
584 GST_cfg = c; 599 GST_keygen = NULL;
585 if (GNUNET_OK != 600 if (NULL == pk)
586 GNUNET_CONFIGURATION_get_value_filename (c, "GNUNETD", "HOSTKEY",
587 &keyfile))
588 {
589 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
590 _
591 ("Transport service is lacking key configuration settings. Exiting.\n"));
592 GNUNET_SCHEDULER_shutdown ();
593 return;
594 }
595 GST_my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
596 GNUNET_free (keyfile);
597 if (GST_my_private_key == NULL)
598 { 601 {
599 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 602 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
600 _("Transport service could not access hostkey. Exiting.\n")); 603 _("Transport service could not access hostkey: %s. Exiting.\n"),
604 emsg);
601 GNUNET_SCHEDULER_shutdown (); 605 GNUNET_SCHEDULER_shutdown ();
602 return; 606 return;
603 } 607 }
604 GST_stats = GNUNET_STATISTICS_create ("transport", c); 608 GST_my_private_key = pk;
605 GST_peerinfo = GNUNET_PEERINFO_connect (c); 609
610 GST_stats = GNUNET_STATISTICS_create ("transport", GST_cfg);
611 GST_peerinfo = GNUNET_PEERINFO_connect (GST_cfg);
606 memset (&GST_my_public_key, '\0', sizeof (GST_my_public_key)); 612 memset (&GST_my_public_key, '\0', sizeof (GST_my_public_key));
607 memset (&tmp, '\0', sizeof (tmp)); 613 memset (&tmp, '\0', sizeof (tmp));
608 GNUNET_CRYPTO_rsa_key_get_public (GST_my_private_key, &GST_my_public_key); 614 GNUNET_CRYPTO_rsa_key_get_public (GST_my_private_key, &GST_my_public_key);
@@ -614,7 +620,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
614 620
615 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, 621 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
616 NULL); 622 NULL);
617 if (GST_peerinfo == NULL) 623 if (NULL == GST_peerinfo)
618 { 624 {
619 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 625 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
620 _("Could not access PEERINFO service. Exiting.\n")); 626 _("Could not access PEERINFO service. Exiting.\n"));
@@ -625,7 +631,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
625 /* start subsystems */ 631 /* start subsystems */
626 GST_hello_start (&process_hello_update, NULL); 632 GST_hello_start (&process_hello_update, NULL);
627 GNUNET_assert (NULL != GST_hello_get()); 633 GNUNET_assert (NULL != GST_hello_get());
628 GST_blacklist_start (server); 634 GST_blacklist_start (GST_server);
629 GST_ats = 635 GST_ats =
630 GNUNET_ATS_scheduling_init (GST_cfg, &ats_request_address_change, NULL); 636 GNUNET_ATS_scheduling_init (GST_cfg, &ats_request_address_change, NULL);
631 GST_plugins_load (&plugin_env_receive_callback, 637 GST_plugins_load (&plugin_env_receive_callback,
@@ -636,8 +642,47 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
636 &neighbours_connect_notification, 642 &neighbours_connect_notification,
637 &neighbours_disconnect_notification, 643 &neighbours_disconnect_notification,
638 &neighbours_address_notification); 644 &neighbours_address_notification);
639 GST_clients_start (server); 645 GST_clients_start (GST_server);
640 GST_validation_start (); 646 GST_validation_start ();
647 GNUNET_SERVER_resume (GST_server);
648}
649
650
651/**
652 * Initiate transport service.
653 *
654 * @param cls closure
655 * @param server the initialized server
656 * @param c configuration to use
657 */
658static void
659run (void *cls, struct GNUNET_SERVER_Handle *server,
660 const struct GNUNET_CONFIGURATION_Handle *c)
661{
662 char *keyfile;
663
664 /* setup globals */
665 GST_cfg = c;
666 if (GNUNET_OK !=
667 GNUNET_CONFIGURATION_get_value_filename (c, "GNUNETD", "HOSTKEY",
668 &keyfile))
669 {
670 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
671 _
672 ("Transport service is lacking key configuration settings. Exiting.\n"));
673 GNUNET_SCHEDULER_shutdown ();
674 return;
675 }
676 GST_server = server;
677 GNUNET_SERVER_suspend (server);
678 GST_keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, &key_generation_cb, NULL);
679 GNUNET_free (keyfile);
680 if (NULL == GST_keygen)
681 {
682 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
683 _("Transport service is unable to access hostkey. Exiting.\n"));
684 GNUNET_SCHEDULER_shutdown ();
685 }
641} 686}
642 687
643 688
diff --git a/src/transport/test_plugin_transport.c b/src/transport/test_plugin_transport.c
index e6a016c51..6882f919c 100644
--- a/src/transport/test_plugin_transport.c
+++ b/src/transport/test_plugin_transport.c
@@ -139,6 +139,7 @@ struct AddressWrapper
139 char *addrstring; 139 char *addrstring;
140}; 140};
141 141
142
142static void 143static void
143end () 144end ()
144{ 145{
@@ -186,6 +187,7 @@ end ()
186 } 187 }
187} 188}
188 189
190
189static void 191static void
190end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 192end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
191{ 193{
@@ -245,6 +247,7 @@ end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
245 ok = 1; 247 ok = 1;
246} 248}
247 249
250
248static void 251static void
249wait_end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 252wait_end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
250{ 253{
@@ -290,6 +293,7 @@ env_receive (void *cls,
290 293
291static int got_reply; 294static int got_reply;
292 295
296
293/** 297/**
294 * Take the given address and append it to the set of results sent back to 298 * Take the given address and append it to the set of results sent back to
295 * the client. 299 * the client.
@@ -435,7 +439,8 @@ env_notify_address (void *cls,
435 } 439 }
436} 440}
437 441
438struct GNUNET_ATS_Information 442
443static struct GNUNET_ATS_Information
439env_get_address_type (void *cls, 444env_get_address_type (void *cls,
440 const struct sockaddr *addr, 445 const struct sockaddr *addr,
441 size_t addrlen) 446 size_t addrlen)
@@ -446,19 +451,22 @@ env_get_address_type (void *cls,
446 return ats; 451 return ats;
447} 452}
448 453
449const struct GNUNET_MessageHeader * 454
450env_get_our_hello (void) 455static const struct GNUNET_MessageHeader *
456env_get_our_hello ()
451{ 457{
452 return (const struct GNUNET_MessageHeader *) hello; 458 return (const struct GNUNET_MessageHeader *) hello;
453} 459}
454 460
455void env_session_end (void *cls,
456 const struct GNUNET_PeerIdentity *peer,
457 struct Session * session)
458{
459 461
462static void
463env_session_end (void *cls,
464 const struct GNUNET_PeerIdentity *peer,
465 struct Session * session)
466{
460} 467}
461 468
469
462static void 470static void
463setup_plugin_environment () 471setup_plugin_environment ()
464{ 472{
@@ -482,6 +490,7 @@ handle_helper_message (void *cls, void *client,
482 return GNUNET_OK; 490 return GNUNET_OK;
483} 491}
484 492
493
485/** 494/**
486 * Runs the test. 495 * Runs the test.
487 * 496 *
@@ -502,33 +511,31 @@ run (void *cls, char *const *args, const char *cfgfile,
502 511
503 cfg = c; 512 cfg = c;
504 /* parse configuration */ 513 /* parse configuration */
505 if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (c, 514 if ( (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (c,
506 "TRANSPORT", 515 "TRANSPORT",
507 "NEIGHBOUR_LIMIT", 516 "NEIGHBOUR_LIMIT",
508 &tneigh)) || 517 &tneigh)) ||
509 (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (c, 518 (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (c,
510 "GNUNETD", "HOSTKEY", 519 "GNUNETD", "HOSTKEY",
511 &keyfile))) 520 &keyfile)))
512 { 521 {
513 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 522 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
514 _("Transport service is lacking key configuration settings. Exiting.\n")); 523 _("Transport service is lacking key configuration settings. Exiting.\n"));
515
516 return; 524 return;
517 } 525 }
518 526
519 stats = GNUNET_STATISTICS_create ("transport", cfg); 527 if (NULL == (stats = GNUNET_STATISTICS_create ("transport", cfg)))
520 if (NULL == stats)
521 { 528 {
522 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 529 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
523 _("Could not create statistics. Exiting.\n")); 530 _("Could not create statistics. Exiting.\n"));
524 end_badly_now (); 531 end_badly_now ();
525 return; 532 return;
526 } 533 }
527 534
528 max_connect_per_transport = (uint32_t) tneigh; 535 max_connect_per_transport = (uint32_t) tneigh;
529 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); 536 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
530 GNUNET_free (keyfile); 537 GNUNET_free (keyfile);
531 if (my_private_key == NULL) 538 if (NULL == my_private_key)
532 { 539 {
533 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 540 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
534 _("Transport service could not access hostkey. Exiting.\n")); 541 _("Transport service could not access hostkey. Exiting.\n"));
@@ -638,7 +645,7 @@ run (void *cls, char *const *args, const char *cfgfile,
638 645
639 646
640/** 647/**
641 * The main function for the transport service. 648 * The main function for the test
642 * 649 *
643 * @param argc number of arguments from the command line 650 * @param argc number of arguments from the command line
644 * @param argv command line arguments 651 * @param argv command line arguments
@@ -656,20 +663,19 @@ main (int argc, char *const *argv)
656 "test_plugin_transport", 663 "test_plugin_transport",
657 "-c", 664 "-c",
658 "test_plugin_transport_data.conf", 665 "test_plugin_transport_data.conf",
659 "-L", "WARNING",
660 NULL 666 NULL
661 }; 667 };
662 GNUNET_log_setup ("test-plugin-transport", 668 GNUNET_log_setup ("test-plugin-transport",
663 "WARNING", 669 "WARNING",
664 NULL); 670 NULL);
665 ok = 1; /* set to fail */ 671 ok = 1; /* set to fail */
666 ret = (GNUNET_OK == GNUNET_PROGRAM_run (5, 672 ret = (GNUNET_OK == GNUNET_PROGRAM_run (3,
667 argv_prog, 673 argv_prog,
668 "test-plugin-transport", 674 "test-plugin-transport",
669 "testcase", 675 "testcase",
670 options, 676 options,
671 &run, 677 &run,
672 (void *) argv)) ? ok : 1; 678 (void *) argv)) ? ok : 1;
673 GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-plugin-transport"); 679 GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-plugin-transport");
674 return ret; 680 return ret;
675} 681}
diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c
index dbf71d78a..8dce1080c 100644
--- a/src/util/crypto_random.c
+++ b/src/util/crypto_random.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other contributing authors) 3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2012 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -34,6 +34,14 @@
34 34
35#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) 35#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
36 36
37
38/**
39 * GNUNET_YES if we are using a 'weak' (low-entropy) PRNG.
40 */
41static int weak_random;
42
43
44
37/* TODO: ndurner, move this to plibc? */ 45/* TODO: ndurner, move this to plibc? */
38/* The code is derived from glibc, obviously */ 46/* The code is derived from glibc, obviously */
39#if MINGW 47#if MINGW
@@ -49,14 +57,18 @@
49#undef RAND_MAX 57#undef RAND_MAX
50#endif 58#endif
51#define RAND_MAX 0x7fffffff /* Hopefully this is correct */ 59#define RAND_MAX 0x7fffffff /* Hopefully this is correct */
60
61
52static int32_t glibc_weak_rand32_state = 1; 62static int32_t glibc_weak_rand32_state = 1;
53 63
64
54void 65void
55glibc_weak_srand32 (int32_t s) 66glibc_weak_srand32 (int32_t s)
56{ 67{
57 glibc_weak_rand32_state = s; 68 glibc_weak_rand32_state = s;
58} 69}
59 70
71
60int32_t 72int32_t
61glibc_weak_rand32 () 73glibc_weak_rand32 ()
62{ 74{
@@ -74,11 +86,12 @@ glibc_weak_rand32 ()
74 * @return number between 0 and 1. 86 * @return number between 0 and 1.
75 */ 87 */
76static double 88static double
77weak_random () 89get_weak_random ()
78{ 90{
79 return ((double) RANDOM () / RAND_MAX); 91 return ((double) RANDOM () / RAND_MAX);
80} 92}
81 93
94
82/** 95/**
83 * Seed a weak random generator. Only GNUNET_CRYPTO_QUALITY_WEAK-mode generator 96 * Seed a weak random generator. Only GNUNET_CRYPTO_QUALITY_WEAK-mode generator
84 * can be seeded. 97 * can be seeded.
@@ -91,6 +104,7 @@ GNUNET_CRYPTO_seed_weak_random (int32_t seed)
91 SRANDOM (seed); 104 SRANDOM (seed);
92} 105}
93 106
107
94/** 108/**
95 * Produce a random value. 109 * Produce a random value.
96 * 110 *
@@ -134,7 +148,7 @@ GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i)
134 while (ret >= ul); 148 while (ret >= ul);
135 return ret % i; 149 return ret % i;
136 case GNUNET_CRYPTO_QUALITY_WEAK: 150 case GNUNET_CRYPTO_QUALITY_WEAK:
137 ret = i * weak_random (); 151 ret = i * get_weak_random ();
138 if (ret >= i) 152 if (ret >= i)
139 ret = i - 1; 153 ret = i - 1;
140 return ret; 154 return ret;
@@ -211,7 +225,7 @@ GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max)
211 225
212 return ret % max; 226 return ret % max;
213 case GNUNET_CRYPTO_QUALITY_WEAK: 227 case GNUNET_CRYPTO_QUALITY_WEAK:
214 ret = max * weak_random (); 228 ret = max * get_weak_random ();
215 if (ret >= max) 229 if (ret >= max)
216 ret = max - 1; 230 ret = max - 1;
217 return ret; 231 return ret;
@@ -221,6 +235,19 @@ GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max)
221 return 0; 235 return 0;
222} 236}
223 237
238
239/**
240 * Check if we are using weak random number generation.
241 *
242 * @return GNUNET_YES if weak number generation is on
243 */
244int
245GNUNET_CRYPTO_random_is_weak ()
246{
247 return weak_random;
248}
249
250
224/** 251/**
225 * This function should only be called in testcases 252 * This function should only be called in testcases
226 * where strong entropy gathering is not desired 253 * where strong entropy gathering is not desired
@@ -229,6 +256,7 @@ GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max)
229void 256void
230GNUNET_CRYPTO_random_disable_entropy_gathering () 257GNUNET_CRYPTO_random_disable_entropy_gathering ()
231{ 258{
259 weak_random = GNUNET_YES;
232 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); 260 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
233} 261}
234 262
@@ -239,6 +267,7 @@ GNUNET_CRYPTO_random_disable_entropy_gathering ()
239 */ 267 */
240static struct GNUNET_OS_Process *genproc; 268static struct GNUNET_OS_Process *genproc;
241 269
270
242/** 271/**
243 * Function called by libgcrypt whenever we are 272 * Function called by libgcrypt whenever we are
244 * blocked gathering entropy. 273 * blocked gathering entropy.
diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c
index 4afda1f6e..8843464a2 100644
--- a/src/util/crypto_rsa.c
+++ b/src/util/crypto_rsa.c
@@ -629,11 +629,17 @@ try_read_key (const char *filename)
629 (void) GNUNET_DISK_file_close (fd); 629 (void) GNUNET_DISK_file_close (fd);
630 return NULL; 630 return NULL;
631 } 631 }
632 if (0 == fs)
633 {
634 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd));
635 return NULL;
636 }
632 if (fs > UINT16_MAX) 637 if (fs > UINT16_MAX)
633 { 638 {
634 LOG (GNUNET_ERROR_TYPE_ERROR, 639 LOG (GNUNET_ERROR_TYPE_ERROR,
635 _("File `%s' does not contain a valid private key. Deleting it.\n"), 640 _("File `%s' does not contain a valid private key (too long, %llu bytes). Deleting it.\n"),
636 filename); 641 filename,
642 (unsigned long long) fs);
637 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd)); 643 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd));
638 if (0 != UNLINK (filename)) 644 if (0 != UNLINK (filename))
639 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); 645 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename);
@@ -648,8 +654,9 @@ try_read_key (const char *filename)
648 (NULL == (ret = GNUNET_CRYPTO_rsa_decode_key ((char *) enc, len)))) 654 (NULL == (ret = GNUNET_CRYPTO_rsa_decode_key ((char *) enc, len))))
649 { 655 {
650 LOG (GNUNET_ERROR_TYPE_ERROR, 656 LOG (GNUNET_ERROR_TYPE_ERROR,
651 _("File `%s' does not contain a valid private key. Deleting it.\n"), 657 _("File `%s' does not contain a valid private key (failed decode, %llu bytes). Deleting it.\n"),
652 filename); 658 filename,
659 (unsigned long long) fs);
653 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd)); 660 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd));
654 if (0 != UNLINK (filename)) 661 if (0 != UNLINK (filename))
655 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); 662 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename);
@@ -664,6 +671,23 @@ try_read_key (const char *filename)
664 671
665 672
666/** 673/**
674 * Wait for a short time (we're trying to lock a file or want
675 * to give another process a shot at finishing a disk write, etc.).
676 * Sleeps for 100ms (as that should be long enough for virtually all
677 * modern systems to context switch and allow another process to do
678 * some 'real' work).
679 */
680static void
681short_wait ()
682{
683 struct GNUNET_TIME_Relative timeout;
684
685 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100);
686 GNUNET_NETWORK_socket_select (NULL, NULL, NULL, timeout);
687}
688
689
690/**
667 * Create a new private key by reading it from a file. If the 691 * Create a new private key by reading it from a file. If the
668 * files does not exist, create a new key and write it to the 692 * files does not exist, create a new key and write it to the
669 * file. Caller must free return value. Note that this function 693 * file. Caller must free return value. Note that this function
@@ -723,7 +747,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
723 sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded), 747 sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded),
724 GNUNET_YES)) 748 GNUNET_YES))
725 { 749 {
726 sleep (1); 750 short_wait (1);
727 if (0 == ++cnt % 10) 751 if (0 == ++cnt % 10)
728 { 752 {
729 ec = errno; 753 ec = errno;
@@ -781,7 +805,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
781 _ 805 _
782 ("This may be ok if someone is currently generating a hostkey.\n")); 806 ("This may be ok if someone is currently generating a hostkey.\n"));
783 } 807 }
784 sleep (1); 808 short_wait (1);
785 continue; 809 continue;
786 } 810 }
787 if (GNUNET_YES != GNUNET_DISK_file_test (filename)) 811 if (GNUNET_YES != GNUNET_DISK_file_test (filename))
@@ -817,7 +841,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
817 _ 841 _
818 ("This may be ok if someone is currently generating a hostkey.\n")); 842 ("This may be ok if someone is currently generating a hostkey.\n"));
819 } 843 }
820 sleep (2); /* wait a bit longer! */ 844 short_wait (1); /* wait a bit longer! */
821 continue; 845 continue;
822 } 846 }
823 break; 847 break;
@@ -996,6 +1020,7 @@ GNUNET_CRYPTO_rsa_key_create_start (const char *filename,
996{ 1020{
997 struct GNUNET_CRYPTO_RsaKeyGenerationContext *gc; 1021 struct GNUNET_CRYPTO_RsaKeyGenerationContext *gc;
998 struct GNUNET_CRYPTO_RsaPrivateKey *pk; 1022 struct GNUNET_CRYPTO_RsaPrivateKey *pk;
1023 const char *weak_random;
999 1024
1000 if (NULL != (pk = try_read_key (filename))) 1025 if (NULL != (pk = try_read_key (filename)))
1001 { 1026 {
@@ -1023,13 +1048,18 @@ GNUNET_CRYPTO_rsa_key_create_start (const char *filename,
1023 GNUNET_free (gc); 1048 GNUNET_free (gc);
1024 return NULL; 1049 return NULL;
1025 } 1050 }
1051 weak_random = NULL;
1052 if (GNUNET_YES ==
1053 GNUNET_CRYPTO_random_is_weak ())
1054 weak_random = "-w";
1026 gc->gnunet_rsa = GNUNET_OS_start_process (GNUNET_NO, 1055 gc->gnunet_rsa = GNUNET_OS_start_process (GNUNET_NO,
1027 GNUNET_OS_INHERIT_STD_ERR, 1056 GNUNET_OS_INHERIT_STD_ERR,
1028 NULL, 1057 NULL,
1029 gc->gnunet_rsa_out, 1058 gc->gnunet_rsa_out,
1030 "gnunet-rsa", 1059 "gnunet-rsa",
1031 "gnunet-rsa", 1060 "gnunet-rsa",
1032 gc->filename, 1061 gc->filename,
1062 weak_random,
1033 NULL); 1063 NULL);
1034 if (NULL == gc->gnunet_rsa) 1064 if (NULL == gc->gnunet_rsa)
1035 { 1065 {
diff --git a/src/util/gnunet-rsa.c b/src/util/gnunet-rsa.c
index 61e1b66df..e9fbf15df 100644
--- a/src/util/gnunet-rsa.c
+++ b/src/util/gnunet-rsa.c
@@ -43,6 +43,11 @@ static int print_peer_identity;
43 */ 43 */
44static int print_short_identity; 44static int print_short_identity;
45 45
46/**
47 * Use weak random number generator for key generation.
48 */
49static int weak_random;
50
46 51
47/** 52/**
48 * The private information of an RSA key pair. 53 * The private information of an RSA key pair.
@@ -104,6 +109,8 @@ run (void *cls, char *const *args, const char *cfgfile,
104 fprintf (stderr, _("No hostkey file specified on command line\n")); 109 fprintf (stderr, _("No hostkey file specified on command line\n"));
105 return; 110 return;
106 } 111 }
112 if (0 != weak_random)
113 GNUNET_CRYPTO_random_disable_entropy_gathering ();
107 pk = GNUNET_CRYPTO_rsa_key_create_from_file (args[0]); 114 pk = GNUNET_CRYPTO_rsa_key_create_from_file (args[0]);
108 if (NULL == pk) 115 if (NULL == pk)
109 return; 116 return;
@@ -159,6 +166,9 @@ main (int argc, char *const *argv)
159 { 's', "print-short-identity", NULL, 166 { 's', "print-short-identity", NULL,
160 gettext_noop ("print the short hash of the public key in ASCII format"), 167 gettext_noop ("print the short hash of the public key in ASCII format"),
161 0, &GNUNET_GETOPT_set_one, &print_short_identity }, 168 0, &GNUNET_GETOPT_set_one, &print_short_identity },
169 { 'w', "weak-random", NULL,
170 gettext_noop ("use insecure, weak random number generator for key generation (for testing only)"),
171 0, &GNUNET_GETOPT_set_one, &weak_random },
162 GNUNET_GETOPT_OPTION_END 172 GNUNET_GETOPT_OPTION_END
163 }; 173 };
164 174
diff --git a/src/util/server.c b/src/util/server.c
index ff4584677..4622e0779 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -334,43 +334,6 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
334 334
335 335
336/** 336/**
337 * Add a listen task with the scheduler for this server.
338 *
339 * @param server handle to our server for which we are adding the listen
340 * socket
341 */
342static void
343schedule_listen_task (struct GNUNET_SERVER_Handle *server)
344{
345 struct GNUNET_NETWORK_FDSet *r;
346 unsigned int i;
347
348 if (NULL == server->listen_sockets[0])
349 return; /* nothing to do, no listen sockets! */
350 if (NULL == server->listen_sockets[1])
351 {
352 /* simplified method: no fd set needed; this is then much simpler and
353 much more efficient */
354 server->listen_task =
355 GNUNET_SCHEDULER_add_read_net_with_priority (GNUNET_TIME_UNIT_FOREVER_REL,
356 GNUNET_SCHEDULER_PRIORITY_HIGH,
357 server->listen_sockets[0],
358 &process_listen_socket, server);
359 return;
360 }
361 r = GNUNET_NETWORK_fdset_create ();
362 i = 0;
363 while (NULL != server->listen_sockets[i])
364 GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
365 server->listen_task =
366 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
367 GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
368 &process_listen_socket, server);
369 GNUNET_NETWORK_fdset_destroy (r);
370}
371
372
373/**
374 * Scheduler says our listen socket is ready. Process it! 337 * Scheduler says our listen socket is ready. Process it!
375 * 338 *
376 * @param cls handle to our server for which we are processing the listen 339 * @param cls handle to our server for which we are processing the listen
@@ -389,7 +352,7 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
389 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 352 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
390 { 353 {
391 /* ignore shutdown, someone else will take care of it! */ 354 /* ignore shutdown, someone else will take care of it! */
392 schedule_listen_task (server); 355 GNUNET_SERVER_resume (server);
393 return; 356 return;
394 } 357 }
395 i = 0; 358 i = 0;
@@ -412,7 +375,7 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
412 i++; 375 i++;
413 } 376 }
414 /* listen for more! */ 377 /* listen for more! */
415 schedule_listen_task (server); 378 GNUNET_SERVER_resume (server);
416} 379}
417 380
418 381
@@ -536,7 +499,7 @@ GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access,
536 server->access_cls = access_cls; 499 server->access_cls = access_cls;
537 server->require_found = require_found; 500 server->require_found = require_found;
538 if (NULL != lsocks) 501 if (NULL != lsocks)
539 schedule_listen_task (server); 502 GNUNET_SERVER_resume (server);
540 return server; 503 return server;
541} 504}
542 505
@@ -671,6 +634,58 @@ test_monitor_clients (struct GNUNET_SERVER_Handle *server)
671 634
672 635
673/** 636/**
637 * Suspend accepting connections from the listen socket temporarily.
638 *
639 * @param server server to stop accepting connections.
640 */
641void
642GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server)
643{
644 if (GNUNET_SCHEDULER_NO_TASK != server->listen_task)
645 {
646 GNUNET_SCHEDULER_cancel (server->listen_task);
647 server->listen_task = GNUNET_SCHEDULER_NO_TASK;
648 }
649}
650
651
652/**
653 * Resume accepting connections from the listen socket.
654 *
655 * @param server server to stop accepting connections.
656 */
657void
658GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server)
659{
660 struct GNUNET_NETWORK_FDSet *r;
661 unsigned int i;
662
663 if (NULL == server->listen_sockets[0])
664 return; /* nothing to do, no listen sockets! */
665 if (NULL == server->listen_sockets[1])
666 {
667 /* simplified method: no fd set needed; this is then much simpler and
668 much more efficient */
669 server->listen_task =
670 GNUNET_SCHEDULER_add_read_net_with_priority (GNUNET_TIME_UNIT_FOREVER_REL,
671 GNUNET_SCHEDULER_PRIORITY_HIGH,
672 server->listen_sockets[0],
673 &process_listen_socket, server);
674 return;
675 }
676 r = GNUNET_NETWORK_fdset_create ();
677 i = 0;
678 while (NULL != server->listen_sockets[i])
679 GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
680 server->listen_task =
681 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
682 GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
683 &process_listen_socket, server);
684 GNUNET_NETWORK_fdset_destroy (r);
685}
686
687
688/**
674 * Stop the listen socket and get ready to shutdown the server 689 * Stop the listen socket and get ready to shutdown the server
675 * once only 'monitor' clients are left. 690 * once only 'monitor' clients are left.
676 * 691 *