~ubuntu-branches/ubuntu/intrepid/gnunet/intrepid

« back to all changes in this revision

Viewing changes to src/applications/testing/testing.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2008-07-03 14:17:00 UTC
  • mfrom: (1.2.11 upstream) (16 hardy)
  • mto: This revision was merged to the branch mainline in revision 23.
  • Revision ID: james.westby@ubuntu.com-20080703141700-355g0g164kaw2kwk
Tags: 0.8.0-2
* Creating /var/run/gnunetd in initscript in case /var/run is on a tmpfs.
* Adding versioned conflicts/replaces against gnunet in order to allow etch to
  lenny upgrades.
* Updating contact address in po files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
     This file is part of GNUnet.
 
3
     (C) 2008 Christian Grothoff (and other contributing authors)
 
4
 
 
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.
 
9
 
 
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.
 
14
 
 
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.
 
19
*/
 
20
 
 
21
/**
 
22
 * @file applications/testing/testing.c
 
23
 * @brief testcase for testing library
 
24
 * @author Christian Grothoff
 
25
 */
 
26
 
 
27
#include "platform.h"
 
28
#include "gnunet_protocols.h"
 
29
#include "gnunet_identity_lib.h"
 
30
#include "gnunet_util.h"
 
31
#include "gnunet_testing_lib.h"
 
32
 
 
33
#define VERBOSE GNUNET_NO
 
34
 
 
35
static void
 
36
updatePort (struct GNUNET_GC_Configuration *cfg,
 
37
            const char *section, unsigned short offset)
 
38
{
 
39
  unsigned long long old;
 
40
 
 
41
  if ((GNUNET_YES == GNUNET_GC_have_configuration_value (cfg,
 
42
                                                         section,
 
43
                                                         "PORT")) &&
 
44
      (0 == GNUNET_GC_get_configuration_value_number (cfg,
 
45
                                                      section,
 
46
                                                      "PORT",
 
47
                                                      0, 65535, 65535, &old)))
 
48
    {
 
49
      old += offset;
 
50
      GNUNET_GE_ASSERT (NULL,
 
51
                        0 == GNUNET_GC_set_configuration_value_number (cfg,
 
52
                                                                       NULL,
 
53
                                                                       section,
 
54
                                                                       "PORT",
 
55
                                                                       old));
 
56
    }
 
57
}
 
58
 
 
59
/**
 
60
 * Starts a gnunet daemon.
 
61
 *
 
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
 
70
 */
 
71
int
 
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,
 
77
                             pid_t * pid,
 
78
                             GNUNET_PeerIdentity * peer, char **configFile)
 
79
{
 
80
  int ret;
 
81
  char *ipath;
 
82
  char *dpath;
 
83
  struct GNUNET_GC_Configuration *cfg;
 
84
  char host[128];
 
85
  struct GNUNET_ClientServerConnection *sock;
 
86
  GNUNET_MessageHello *hello;
 
87
  int round;
 
88
 
 
89
  fprintf (stderr, "Starting peer on port %u\n", app_port);
 
90
#if 0
 
91
  /* do not usually do this -- may easily
 
92
     exhaust entropy pool for hostkey generation... */
 
93
  GNUNET_disk_directory_remove (NULL, gnunetd_home);
 
94
#endif
 
95
  ipath = GNUNET_get_installation_path (GNUNET_IPK_DATADIR);
 
96
  if (ipath == NULL)
 
97
    return GNUNET_SYSERR;
 
98
  dpath = GNUNET_malloc (strlen (ipath) + 128);
 
99
  strcpy (dpath, ipath);
 
100
  GNUNET_free (ipath);
 
101
  strcat (dpath, DIR_SEPARATOR_STR "gnunet-testing.conf");
 
102
  cfg = GNUNET_GC_create ();
 
103
  if (-1 == GNUNET_GC_parse_configuration (cfg, dpath))
 
104
    {
 
105
      fprintf (stderr,
 
106
               "Failed to read default configuration file `%s'\n", dpath);
 
107
      GNUNET_GC_free (cfg);
 
108
      GNUNET_free (dpath);
 
109
      return GNUNET_SYSERR;
 
110
    }
 
111
  GNUNET_free (dpath);
 
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,
 
117
                                            NULL,
 
118
                                            "PATHS", "GNUNETD_HOME",
 
119
                                            gnunetd_home);
 
120
  if (transports != NULL)
 
121
    GNUNET_GC_set_configuration_value_string (cfg,
 
122
                                              NULL,
 
123
                                              "GNUNETD", "TRANSPORTS",
 
124
                                              transports);
 
125
  if (applications != NULL)
 
126
    GNUNET_GC_set_configuration_value_string (cfg,
 
127
                                              NULL,
 
128
                                              "GNUNETD",
 
129
                                              "APPLICATIONS", applications);
 
130
  GNUNET_GC_set_configuration_value_number (cfg, NULL, "NETWORK", "PORT",
 
131
                                            app_port);
 
132
  dpath = GNUNET_strdup ("/tmp/gnunet-config.XXXXXX");
 
133
  ret = mkstemp (dpath);
 
134
  if (ret == -1)
 
135
    {
 
136
      GNUNET_GE_LOG_STRERROR_FILE (NULL,
 
137
                                   GNUNET_GE_ERROR | GNUNET_GE_USER |
 
138
                                   GNUNET_GE_BULK, "mkstemp", dpath);
 
139
      GNUNET_free (dpath);
 
140
      GNUNET_GC_free (cfg);
 
141
      return GNUNET_SYSERR;
 
142
    }
 
143
  CLOSE (ret);
 
144
  if (0 != GNUNET_GC_write_configuration (cfg, dpath))
 
145
    {
 
146
      fprintf (stderr,
 
147
               "Failed to write peer configuration file `%s'\n", dpath);
 
148
      GNUNET_free (dpath);
 
149
      GNUNET_GC_free (cfg);
 
150
      return GNUNET_SYSERR;
 
151
    }
 
152
  GNUNET_GC_free (cfg);
 
153
 
 
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",
 
158
                                            host);
 
159
 
 
160
  ret = GNUNET_daemon_start (NULL, cfg, dpath, GNUNET_NO);
 
161
  if (ret == -1)
 
162
    {
 
163
      fprintf (stderr, "Failed to start daemon!\n");
 
164
      GNUNET_GC_free (cfg);
 
165
      return GNUNET_SYSERR;
 
166
    }
 
167
  *pid = ret;
 
168
 
 
169
  /* now get peer ID */
 
170
  /* we need to wait quite a while since the peers
 
171
     maybe creating public keys and waiting for
 
172
     entropy! */
 
173
  if (GNUNET_OK !=
 
174
      GNUNET_wait_for_daemon_running (NULL, cfg, 60 * GNUNET_CRON_SECONDS))
 
175
    {
 
176
      fprintf (stderr, "Failed to confirm daemon running!\n");
 
177
      GNUNET_GC_free (cfg);
 
178
      UNLINK (dpath);
 
179
      GNUNET_free (dpath);
 
180
      return GNUNET_SYSERR;
 
181
    }
 
182
  *configFile = dpath;
 
183
  dpath = NULL;
 
184
  round = 0;
 
185
  ret = GNUNET_SYSERR;
 
186
  while ((round++ < 20) && (ret == GNUNET_SYSERR))
 
187
    {
 
188
      sock = GNUNET_client_connection_create (NULL, cfg);
 
189
      ret = GNUNET_IDENTITY_get_self (sock, &hello);
 
190
      if (ret == GNUNET_OK)
 
191
        {
 
192
          GNUNET_hash (&hello->publicKey, sizeof (GNUNET_RSA_PublicKey),
 
193
                       &peer->hashPubKey);
 
194
          GNUNET_free (hello);
 
195
        }
 
196
      else
 
197
        {
 
198
          GNUNET_thread_sleep (1500 * GNUNET_CRON_MILLISECONDS);
 
199
        }
 
200
      GNUNET_client_connection_destroy (sock);
 
201
    }
 
202
  GNUNET_GC_free (cfg);
 
203
  if (ret == GNUNET_SYSERR)
 
204
    fprintf (stderr,
 
205
             "Failed to obtain daemon's identity (is a transport loaded?)!\n");
 
206
 
 
207
 
 
208
  return ret;
 
209
}
 
210
 
 
211
#if VERBOSE
 
212
static int
 
213
printInfo (void *data,
 
214
           const GNUNET_PeerIdentity *
 
215
           identity,
 
216
           const void *address,
 
217
           unsigned int addr_len,
 
218
           GNUNET_CronTime last_message,
 
219
           unsigned int trust, unsigned int bpmFromPeer)
 
220
{
 
221
  GNUNET_EncName oth;
 
222
  GNUNET_hash_to_enc (&identity->hashPubKey, &oth);
 
223
  fprintf (stderr,
 
224
           "%s: %llu - %u\n", (const char *) &oth, last_message, bpmFromPeer);
 
225
  return GNUNET_OK;
 
226
}
 
227
#endif
 
228
 
 
229
/**
 
230
 * Establish a connection between two GNUnet daemons
 
231
 * (both must run on this machine).
 
232
 *
 
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
 
236
 */
 
237
int
 
238
GNUNET_TESTING_connect_daemons (unsigned short port1, unsigned short port2)
 
239
{
 
240
  char host[128];
 
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;
 
245
  int ret;
 
246
  GNUNET_MessageHello *h1;
 
247
  GNUNET_MessageHello *h2;
 
248
 
 
249
  ret = GNUNET_SYSERR;
 
250
  GNUNET_snprintf (host, 128, "localhost:%u", port1);
 
251
  GNUNET_GC_set_configuration_value_string (cfg1, NULL, "NETWORK", "HOST",
 
252
                                            host);
 
253
  GNUNET_snprintf (host, 128, "localhost:%u", port2);
 
254
  GNUNET_GC_set_configuration_value_string (cfg2, NULL, "NETWORK", "HOST",
 
255
                                            host);
 
256
  if ((GNUNET_OK ==
 
257
       GNUNET_wait_for_daemon_running (NULL, cfg1, 300 * GNUNET_CRON_SECONDS))
 
258
      && (GNUNET_OK ==
 
259
          GNUNET_wait_for_daemon_running (NULL, cfg2,
 
260
                                          300 * GNUNET_CRON_SECONDS)))
 
261
    {
 
262
      sock1 = GNUNET_client_connection_create (NULL, cfg1);
 
263
      sock2 = GNUNET_client_connection_create (NULL, cfg2);
 
264
      ret = -20;
 
265
      fprintf (stderr, _("Waiting for peers to connect"));
 
266
      while ((ret++ < -1) && (GNUNET_shutdown_test () == GNUNET_NO))
 
267
        {
 
268
          h1 = NULL;
 
269
          h2 = NULL;
 
270
          if ((GNUNET_OK == GNUNET_IDENTITY_get_self (sock1,
 
271
                                                      &h1)) &&
 
272
              (GNUNET_OK == GNUNET_IDENTITY_get_self (sock2,
 
273
                                                      &h2)) &&
 
274
              (GNUNET_OK == GNUNET_IDENTITY_peer_add (sock1,
 
275
                                                      h2)) &&
 
276
              (GNUNET_OK == GNUNET_IDENTITY_peer_add (sock2, h1)))
 
277
            {
 
278
              fprintf (stderr, ".");
 
279
              if (GNUNET_YES == GNUNET_IDENTITY_request_connect (sock1,
 
280
                                                                 &h2->senderIdentity))
 
281
                {
 
282
                  ret = GNUNET_OK;
 
283
                  GNUNET_free_non_null (h1);
 
284
                  GNUNET_free_non_null (h2);
 
285
                  break;
 
286
                }
 
287
              if (GNUNET_YES == GNUNET_IDENTITY_request_connect (sock2,
 
288
                                                                 &h1->senderIdentity))
 
289
                {
 
290
                  ret = GNUNET_OK;
 
291
                  GNUNET_free_non_null (h1);
 
292
                  GNUNET_free_non_null (h2);
 
293
                  break;
 
294
                }
 
295
              GNUNET_thread_sleep (1500 * GNUNET_CRON_MILLISECONDS);
 
296
            }
 
297
          GNUNET_free_non_null (h1);
 
298
          GNUNET_free_non_null (h2);
 
299
        }
 
300
      if (ret != GNUNET_OK)
 
301
        {
 
302
#if VERBOSE
 
303
          GNUNET_EncName e1;
 
304
          GNUNET_EncName e2;
 
305
          GNUNET_hash_to_enc (&h1->senderIdentity.hashPubKey, &e1);
 
306
          GNUNET_hash_to_enc (&h2->senderIdentity.hashPubKey, &e2);
 
307
          fprintf (stderr,
 
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);
 
314
#endif
 
315
        }
 
316
      fprintf (stderr, "%s\n", ret == GNUNET_OK ? "!" : "?");
 
317
      GNUNET_client_connection_destroy (sock1);
 
318
      GNUNET_client_connection_destroy (sock2);
 
319
    }
 
320
  else
 
321
    {
 
322
      fprintf (stderr, "Failed to establish connection with peers.\n");
 
323
    }
 
324
  GNUNET_GC_free (cfg1);
 
325
  GNUNET_GC_free (cfg2);
 
326
  return ret;
 
327
}
 
328
 
 
329
 
 
330
/**
 
331
 * Shutdown the GNUnet daemon waiting on the given port
 
332
 * and running under the given pid.
 
333
 *
 
334
 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
 
335
 */
 
336
int
 
337
GNUNET_TESTING_stop_daemon (unsigned short port, pid_t pid)
 
338
{
 
339
  if (GNUNET_daemon_stop (NULL, pid) != GNUNET_YES)
 
340
    return GNUNET_SYSERR;
 
341
  return GNUNET_OK;
 
342
}
 
343
 
 
344
/**
 
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).
 
349
 *
 
350
 * @return handle used to stop the daemons, NULL on error
 
351
 */
 
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)
 
358
{
 
359
  struct GNUNET_TESTING_DaemonContext *ret;
 
360
  struct GNUNET_TESTING_DaemonContext *nxt;
 
361
  unsigned int pos;
 
362
  char *home;
 
363
  size_t max;
 
364
  pid_t pid;
 
365
  GNUNET_PeerIdentity peer;
 
366
  char *cf;
 
367
 
 
368
  ret = NULL;
 
369
  max = strlen (gnunetd_home_prefix) + 14;
 
370
  home = GNUNET_malloc (max);
 
371
  for (pos = 0; pos < count; pos++)
 
372
    {
 
373
      GNUNET_snprintf (home, max, "%s.%u", gnunetd_home_prefix, pos);
 
374
      if (GNUNET_OK !=
 
375
          GNUNET_TESTING_start_daemon (app_baseport + pos * delta,
 
376
                                       delta * pos, home, transports,
 
377
                                       applications, &pid, &peer, &cf))
 
378
        {
 
379
          GNUNET_TESTING_stop_daemons (ret);
 
380
          ret = NULL;
 
381
          break;
 
382
        }
 
383
      nxt = GNUNET_malloc (sizeof (struct GNUNET_TESTING_DaemonContext));
 
384
      nxt->next = ret;
 
385
      nxt->pid = pid;
 
386
      nxt->peer = peer;
 
387
      nxt->configFile = cf;
 
388
      nxt->port = app_baseport + pos * delta;
 
389
      ret = nxt;
 
390
    }
 
391
  GNUNET_free (home);
 
392
  return ret;
 
393
}
 
394
 
 
395
int
 
396
GNUNET_TESTING_stop_daemons (struct GNUNET_TESTING_DaemonContext *peers)
 
397
{
 
398
  struct GNUNET_TESTING_DaemonContext *next;
 
399
  int ret;
 
400
 
 
401
  ret = GNUNET_OK;
 
402
  while (peers != NULL)
 
403
    {
 
404
      next = peers->next;
 
405
      if (GNUNET_OK != GNUNET_TESTING_stop_daemon (peers->port, peers->pid))
 
406
        ret = GNUNET_SYSERR;
 
407
      UNLINK (peers->configFile);
 
408
      GNUNET_free (peers->configFile);
 
409
      GNUNET_free (peers);
 
410
      peers = next;
 
411
    }
 
412
  return ret;
 
413
}
 
414
 
 
415
 
 
416
 
 
417
/* end of testing.c */