2
This file is part of GNUnet.
3
(C) 2008 Christian Grothoff (and other contributing authors)
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
7
by the Free Software Foundation; either version 2, or (at your
8
option) any later version.
10
GNUnet is distributed in the hope that it will be useful, but
11
WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with GNUnet; see the file COPYING. If not, write to the
17
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
Boston, MA 02111-1307, USA.
22
* @file applications/testing/testing.c
23
* @brief testcase for testing library
24
* @author Christian Grothoff
28
#include "gnunet_protocols.h"
29
#include "gnunet_identity_lib.h"
30
#include "gnunet_util.h"
31
#include "gnunet_testing_lib.h"
33
#define VERBOSE GNUNET_NO
36
updatePort (struct GNUNET_GC_Configuration *cfg,
37
const char *section, unsigned short offset)
39
unsigned long long old;
41
if ((GNUNET_YES == GNUNET_GC_have_configuration_value (cfg,
44
(0 == GNUNET_GC_get_configuration_value_number (cfg,
47
0, 65535, 65535, &old)))
50
GNUNET_GE_ASSERT (NULL,
51
0 == GNUNET_GC_set_configuration_value_number (cfg,
60
* Starts a gnunet daemon.
62
* @param app_port port to listen on for local clients
63
* @param tra_offset offset to add to transport ports
64
* @param gnunetd_home directory to use for the home directory
65
* @param transports transport services that should be loaded
66
* @param applications application services that should be loaded
67
* @param pid of the process (set)
68
* @param peer identity of the peer (set)
69
* @return GNUNET_OK on success, GNUNET_SYSERR on error
72
GNUNET_TESTING_start_daemon (unsigned short app_port,
73
unsigned short tra_offset,
74
const char *gnunetd_home,
75
const char *transports,
76
const char *applications,
78
GNUNET_PeerIdentity * peer, char **configFile)
83
struct GNUNET_GC_Configuration *cfg;
85
struct GNUNET_ClientServerConnection *sock;
86
GNUNET_MessageHello *hello;
89
fprintf (stderr, "Starting peer on port %u\n", app_port);
91
/* do not usually do this -- may easily
92
exhaust entropy pool for hostkey generation... */
93
GNUNET_disk_directory_remove (NULL, gnunetd_home);
95
ipath = GNUNET_get_installation_path (GNUNET_IPK_DATADIR);
98
dpath = GNUNET_malloc (strlen (ipath) + 128);
99
strcpy (dpath, ipath);
101
strcat (dpath, DIR_SEPARATOR_STR "gnunet-testing.conf");
102
cfg = GNUNET_GC_create ();
103
if (-1 == GNUNET_GC_parse_configuration (cfg, dpath))
106
"Failed to read default configuration file `%s'\n", dpath);
107
GNUNET_GC_free (cfg);
109
return GNUNET_SYSERR;
112
updatePort (cfg, "TCP", tra_offset);
113
updatePort (cfg, "UDP", tra_offset);
114
updatePort (cfg, "HTTP", tra_offset);
115
updatePort (cfg, "SMTP", tra_offset);
116
GNUNET_GC_set_configuration_value_string (cfg,
118
"PATHS", "GNUNETD_HOME",
120
if (transports != NULL)
121
GNUNET_GC_set_configuration_value_string (cfg,
123
"GNUNETD", "TRANSPORTS",
125
if (applications != NULL)
126
GNUNET_GC_set_configuration_value_string (cfg,
129
"APPLICATIONS", applications);
130
GNUNET_GC_set_configuration_value_number (cfg, NULL, "NETWORK", "PORT",
132
dpath = GNUNET_strdup ("/tmp/gnunet-config.XXXXXX");
133
ret = mkstemp (dpath);
136
GNUNET_GE_LOG_STRERROR_FILE (NULL,
137
GNUNET_GE_ERROR | GNUNET_GE_USER |
138
GNUNET_GE_BULK, "mkstemp", dpath);
140
GNUNET_GC_free (cfg);
141
return GNUNET_SYSERR;
144
if (0 != GNUNET_GC_write_configuration (cfg, dpath))
147
"Failed to write peer configuration file `%s'\n", dpath);
149
GNUNET_GC_free (cfg);
150
return GNUNET_SYSERR;
152
GNUNET_GC_free (cfg);
154
cfg = GNUNET_GC_create ();
155
/* cfg is now client CFG for GNUNET_daemon_start */
156
GNUNET_snprintf (host, 128, "localhost:%u", app_port);
157
GNUNET_GC_set_configuration_value_string (cfg, NULL, "NETWORK", "HOST",
160
ret = GNUNET_daemon_start (NULL, cfg, dpath, GNUNET_NO);
163
fprintf (stderr, "Failed to start daemon!\n");
164
GNUNET_GC_free (cfg);
165
return GNUNET_SYSERR;
169
/* now get peer ID */
170
/* we need to wait quite a while since the peers
171
maybe creating public keys and waiting for
174
GNUNET_wait_for_daemon_running (NULL, cfg, 60 * GNUNET_CRON_SECONDS))
176
fprintf (stderr, "Failed to confirm daemon running!\n");
177
GNUNET_GC_free (cfg);
180
return GNUNET_SYSERR;
186
while ((round++ < 20) && (ret == GNUNET_SYSERR))
188
sock = GNUNET_client_connection_create (NULL, cfg);
189
ret = GNUNET_IDENTITY_get_self (sock, &hello);
190
if (ret == GNUNET_OK)
192
GNUNET_hash (&hello->publicKey, sizeof (GNUNET_RSA_PublicKey),
198
GNUNET_thread_sleep (1500 * GNUNET_CRON_MILLISECONDS);
200
GNUNET_client_connection_destroy (sock);
202
GNUNET_GC_free (cfg);
203
if (ret == GNUNET_SYSERR)
205
"Failed to obtain daemon's identity (is a transport loaded?)!\n");
213
printInfo (void *data,
214
const GNUNET_PeerIdentity *
217
unsigned int addr_len,
218
GNUNET_CronTime last_message,
219
unsigned int trust, unsigned int bpmFromPeer)
222
GNUNET_hash_to_enc (&identity->hashPubKey, &oth);
224
"%s: %llu - %u\n", (const char *) &oth, last_message, bpmFromPeer);
230
* Establish a connection between two GNUnet daemons
231
* (both must run on this machine).
233
* @param port1 client port of the first daemon
234
* @param port2 client port of the second daemon
235
* @return GNUNET_OK on success, GNUNET_SYSERR on failure
238
GNUNET_TESTING_connect_daemons (unsigned short port1, unsigned short port2)
241
struct GNUNET_GC_Configuration *cfg1 = GNUNET_GC_create ();
242
struct GNUNET_GC_Configuration *cfg2 = GNUNET_GC_create ();
243
struct GNUNET_ClientServerConnection *sock1;
244
struct GNUNET_ClientServerConnection *sock2;
246
GNUNET_MessageHello *h1;
247
GNUNET_MessageHello *h2;
250
GNUNET_snprintf (host, 128, "localhost:%u", port1);
251
GNUNET_GC_set_configuration_value_string (cfg1, NULL, "NETWORK", "HOST",
253
GNUNET_snprintf (host, 128, "localhost:%u", port2);
254
GNUNET_GC_set_configuration_value_string (cfg2, NULL, "NETWORK", "HOST",
257
GNUNET_wait_for_daemon_running (NULL, cfg1, 300 * GNUNET_CRON_SECONDS))
259
GNUNET_wait_for_daemon_running (NULL, cfg2,
260
300 * GNUNET_CRON_SECONDS)))
262
sock1 = GNUNET_client_connection_create (NULL, cfg1);
263
sock2 = GNUNET_client_connection_create (NULL, cfg2);
265
fprintf (stderr, _("Waiting for peers to connect"));
266
while ((ret++ < -1) && (GNUNET_shutdown_test () == GNUNET_NO))
270
if ((GNUNET_OK == GNUNET_IDENTITY_get_self (sock1,
272
(GNUNET_OK == GNUNET_IDENTITY_get_self (sock2,
274
(GNUNET_OK == GNUNET_IDENTITY_peer_add (sock1,
276
(GNUNET_OK == GNUNET_IDENTITY_peer_add (sock2, h1)))
278
fprintf (stderr, ".");
279
if (GNUNET_YES == GNUNET_IDENTITY_request_connect (sock1,
280
&h2->senderIdentity))
283
GNUNET_free_non_null (h1);
284
GNUNET_free_non_null (h2);
287
if (GNUNET_YES == GNUNET_IDENTITY_request_connect (sock2,
288
&h1->senderIdentity))
291
GNUNET_free_non_null (h1);
292
GNUNET_free_non_null (h2);
295
GNUNET_thread_sleep (1500 * GNUNET_CRON_MILLISECONDS);
297
GNUNET_free_non_null (h1);
298
GNUNET_free_non_null (h2);
300
if (ret != GNUNET_OK)
305
GNUNET_hash_to_enc (&h1->senderIdentity.hashPubKey, &e1);
306
GNUNET_hash_to_enc (&h2->senderIdentity.hashPubKey, &e2);
308
"\nFailed to connect `%s' and `%s'\n",
309
(const char *) &e1, (const char *) &e2);
310
fprintf (stderr, "Connections of `%s':\n", (const char *) &e1);
311
GNUNET_IDENTITY_request_peer_infos (sock1, &printInfo, NULL);
312
fprintf (stderr, "Connections of `%s':\n", (const char *) &e2);
313
GNUNET_IDENTITY_request_peer_infos (sock2, &printInfo, NULL);
316
fprintf (stderr, "%s\n", ret == GNUNET_OK ? "!" : "?");
317
GNUNET_client_connection_destroy (sock1);
318
GNUNET_client_connection_destroy (sock2);
322
fprintf (stderr, "Failed to establish connection with peers.\n");
324
GNUNET_GC_free (cfg1);
325
GNUNET_GC_free (cfg2);
331
* Shutdown the GNUnet daemon waiting on the given port
332
* and running under the given pid.
334
* @return GNUNET_OK on success, GNUNET_SYSERR on failure
337
GNUNET_TESTING_stop_daemon (unsigned short port, pid_t pid)
339
if (GNUNET_daemon_stop (NULL, pid) != GNUNET_YES)
340
return GNUNET_SYSERR;
345
* Start count gnunetd processes with the same set of
346
* transports and applications. The port numbers will
347
* be computed by adding "delta" each time (zero
348
* times for the first peer).
350
* @return handle used to stop the daemons, NULL on error
352
struct GNUNET_TESTING_DaemonContext *
353
GNUNET_TESTING_start_daemons (const char *transports,
354
const char *applications,
355
const char *gnunetd_home_prefix,
356
unsigned short app_baseport,
357
unsigned short delta, unsigned int count)
359
struct GNUNET_TESTING_DaemonContext *ret;
360
struct GNUNET_TESTING_DaemonContext *nxt;
365
GNUNET_PeerIdentity peer;
369
max = strlen (gnunetd_home_prefix) + 14;
370
home = GNUNET_malloc (max);
371
for (pos = 0; pos < count; pos++)
373
GNUNET_snprintf (home, max, "%s.%u", gnunetd_home_prefix, pos);
375
GNUNET_TESTING_start_daemon (app_baseport + pos * delta,
376
delta * pos, home, transports,
377
applications, &pid, &peer, &cf))
379
GNUNET_TESTING_stop_daemons (ret);
383
nxt = GNUNET_malloc (sizeof (struct GNUNET_TESTING_DaemonContext));
387
nxt->configFile = cf;
388
nxt->port = app_baseport + pos * delta;
396
GNUNET_TESTING_stop_daemons (struct GNUNET_TESTING_DaemonContext *peers)
398
struct GNUNET_TESTING_DaemonContext *next;
402
while (peers != NULL)
405
if (GNUNET_OK != GNUNET_TESTING_stop_daemon (peers->port, peers->pid))
407
UNLINK (peers->configFile);
408
GNUNET_free (peers->configFile);
417
/* end of testing.c */