-really fix test
[oweals/gnunet.git] / src / gns / test_gns_dht_three_peers.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009 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 3, 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  * @file gns/test_gns_dht_threepeer.c
22  * @brief tests dht lookup over 3 peers
23  *
24  * topology:
25  * alice <----> bob <-----> dave
26  *
27  * alice queries for www.buddy.bob.gnunet
28  *
29  */
30 #include "platform.h"
31 #include "gnunet_common.h"
32 #include "gnunet_disk_lib.h"
33 #include "gnunet_testing_lib-new.h"
34 #include "gnunet_testbed_service.h"
35 #include "gnunet_core_service.h"
36 #include "gnunet_dht_service.h"
37 #include "block_dns.h"
38 #include "gnunet_signatures.h"
39 #include "gnunet_namestore_service.h"
40 #include "gnunet_dnsparser_lib.h"
41 #include "gnunet_gns_service.h"
42
43 #define ZONE_PUT_WAIT_TIME GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30)
44
45 /* If number of peers not in config file, use this number */
46 #define DEFAULT_NUM_PEERS 2
47
48 #define TEST_DOMAIN "www.buddy.bob.gnunet"
49 #define TEST_IP "1.1.1.1"
50 #define TEST_DAVE_PSEU "hagbard"
51 #define TEST_NUM_PEERS 3
52 #define TEST_NUM_CON 3
53
54
55 /* Timeout for entire testcase */
56 #define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 60)
57
58 /* Global return value (0 for success, anything else for failure) */
59 static int ok;
60
61 /* Task handle to use to schedule test failure */
62 GNUNET_SCHEDULER_TaskIdentifier die_task;
63 GNUNET_SCHEDULER_TaskIdentifier wait_task;
64
65 struct GNUNET_CRYPTO_ShortHashCode dave_hash;
66
67 struct GNUNET_CRYPTO_ShortHashCode bob_hash;
68
69 struct GNUNET_TESTBED_Peer **cpeers;
70
71 struct GNUNET_GNS_Handle *gh;
72 struct GNUNET_GNS_LookupRequest *lookup_handle;
73
74 struct GNUNET_TESTBED_Operation *get_cfg_ops[3];
75 struct GNUNET_TESTBED_Operation *connect_ops[3];
76 struct GNUNET_CONFIGURATION_Handle *cfg_handles[3];
77 struct GNUNET_NAMESTORE_Handle *nh[3];
78
79 static int dave_is_setup;
80 static int bob_is_setup;
81 static int alice_is_setup;
82
83 /**
84  * Check if the get_handle is being used, if so stop the request.  Either
85  * way, schedule the end_badly_cont function which actually shuts down the
86  * test.
87  */
88 static void
89 end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
90 {
91   die_task = GNUNET_SCHEDULER_NO_TASK;
92   int c;
93
94   if (GNUNET_SCHEDULER_NO_TASK != wait_task)
95   {
96       GNUNET_SCHEDULER_cancel (wait_task);
97       wait_task = GNUNET_SCHEDULER_NO_TASK;
98   }
99
100   for (c = 0; c < 3; c++)
101   {
102     if (NULL != nh[c])
103     {
104       GNUNET_NAMESTORE_disconnect(nh[c]);
105       nh[c] = NULL;
106     }
107
108     if (NULL != get_cfg_ops[c])
109     {
110         GNUNET_TESTBED_operation_cancel(get_cfg_ops[c]);
111         get_cfg_ops[c] = NULL;
112     }
113     if (NULL != connect_ops[c])
114     {
115         GNUNET_TESTBED_operation_cancel(connect_ops[c]);
116         connect_ops[c] = NULL;
117     }
118     if (NULL != cfg_handles[c])
119     {
120       GNUNET_CONFIGURATION_destroy (cfg_handles[c]);
121       cfg_handles[c] = NULL;
122     }
123   }
124   
125   if (NULL != lookup_handle)
126   {
127     GNUNET_GNS_cancel_lookup_request (lookup_handle);
128     lookup_handle = NULL;
129   }
130   if (NULL != gh)
131   {
132     GNUNET_GNS_disconnect(gh);
133     gh = NULL;
134   }
135   
136   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test failed \n");
137   GNUNET_break (0);
138   GNUNET_SCHEDULER_shutdown ();
139   ok = 1;
140 }
141
142 static void
143 end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
144 {
145   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Finished\n");
146   int c;
147   if (GNUNET_SCHEDULER_NO_TASK != die_task)
148   {
149       GNUNET_SCHEDULER_cancel (die_task);
150       die_task = GNUNET_SCHEDULER_NO_TASK;
151   }
152
153   for (c = 0; c < 3; c++)
154   {
155     if (NULL != nh[c])
156     {
157       GNUNET_NAMESTORE_disconnect(nh[c]);
158       nh[c] = NULL;
159     }
160     if (NULL != cfg_handles[c])
161     {
162       GNUNET_CONFIGURATION_destroy (cfg_handles[c]);
163       cfg_handles[c] = NULL;
164     }
165   }
166
167   if (NULL != gh)
168   {
169     GNUNET_GNS_disconnect(gh);
170     gh = NULL;
171   }
172
173   if (0 == ok)
174     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test ended successful\n");
175   else
176     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test failed\n");
177   GNUNET_SCHEDULER_shutdown ();
178 }
179
180 static void
181 end_now ()
182 {
183   GNUNET_SCHEDULER_add_now (&end, NULL);
184 }
185
186
187 static void
188 disconnect_ns (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
189 {
190
191   GNUNET_NAMESTORE_disconnect (cls);
192   if (cls == nh[0])
193     nh[0] = NULL;
194   if (cls == nh[1])
195     nh[1] = NULL;
196   if (cls == nh[2])
197     nh[2] = NULL;
198 }
199
200
201 static void
202 cont_ns (void* cls, int32_t s, const char* emsg)
203 {
204   GNUNET_SCHEDULER_add_now (&disconnect_ns, cls);
205 }
206
207 static void
208 on_lookup_result(void *cls, uint32_t rd_count,
209                  const struct GNUNET_NAMESTORE_RecordData *rd)
210 {
211   int i;
212   char* string_val;
213
214   if (rd_count == 0)
215   {
216     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
217                 "Lookup failed!\n");
218     ok = 2;
219   }
220   else
221   {
222     ok = 1;
223     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls);
224     for (i=0; i<rd_count; i++)
225     {
226       string_val = GNUNET_NAMESTORE_value_to_string(rd[i].record_type,
227                                                     rd[i].data,
228                                                     rd[i].data_size);
229       if (0 == strcmp(string_val, TEST_IP))
230       {
231         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
232                     "%s correctly resolved to %s!\n", TEST_DOMAIN, string_val);
233         ok = 0;
234       }
235       GNUNET_free (string_val);
236     }
237   }
238   end_now ();
239 }
240
241 static void
242 commence_testing(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
243 {
244   static int wait = 0;
245   wait++;
246   if ((ZONE_PUT_WAIT_TIME.rel_value / 1000) == wait)
247   {
248     fprintf (stderr, "\n");
249     wait_task = GNUNET_SCHEDULER_NO_TASK;
250     lookup_handle = GNUNET_GNS_lookup(gh, TEST_DOMAIN, GNUNET_GNS_RECORD_A,
251                       GNUNET_NO,
252                       NULL,
253                       &on_lookup_result, TEST_DOMAIN);
254     if (GNUNET_SCHEDULER_NO_TASK != die_task)
255       GNUNET_SCHEDULER_cancel(die_task);
256     die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, "from lookup");
257   }
258   else
259   {
260       fprintf (stderr, ".");
261       wait_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &commence_testing, NULL);
262   }
263 }
264
265 void
266 all_connected ()
267 {
268   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Created all connections! Waiting for PUTs\n");
269   wait_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &commence_testing, NULL);
270 }
271
272
273 static void connect_peers ()
274 {
275   static int started;
276   started ++;
277 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "C \n");
278   if (3 == started)
279   {
280       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers started\n");
281
282       connect_ops[0] = GNUNET_TESTBED_overlay_connect (NULL, NULL, NULL,
283                                                        cpeers[0],
284                                                        cpeers[1]);
285
286       connect_ops[1] = GNUNET_TESTBED_overlay_connect (NULL, NULL, NULL,
287                                                        cpeers[1],
288                                                        cpeers[2]);
289
290       connect_ops[2] = GNUNET_TESTBED_overlay_connect (NULL, NULL, NULL,
291                                                        cpeers[0],
292                                                        cpeers[2]);
293   }
294 }
295
296 static int
297 setup_dave (const struct GNUNET_CONFIGURATION_Handle * cfg)
298 {
299   char* keyfile;
300   struct GNUNET_CRYPTO_RsaPrivateKey *key;
301   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
302   struct in_addr *web;
303   struct GNUNET_NAMESTORE_RecordData rd;
304
305   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up dave\n");
306   cfg_handles[0] = GNUNET_CONFIGURATION_dup (cfg);
307   GNUNET_assert (NULL != cfg_handles[0]);
308   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
309                                                             "ZONEKEY",
310                                                             &keyfile))
311   {
312     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
313     return GNUNET_SYSERR;
314   }
315
316   key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
317   if (NULL == key)
318   {
319
320     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
321     GNUNET_free (keyfile);
322     return GNUNET_SYSERR;
323   }
324   nh[0] = GNUNET_NAMESTORE_connect (cfg_handles[0]);
325   if (NULL == nh[0])
326   {
327     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to namestore\n");
328     GNUNET_CRYPTO_rsa_key_free (key);
329     GNUNET_free (keyfile);
330     return GNUNET_SYSERR;
331   }
332
333   GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
334   GNUNET_CRYPTO_short_hash(&pkey, sizeof(pkey), &dave_hash);
335
336   web = GNUNET_malloc(sizeof(struct in_addr));
337   GNUNET_assert(1 == inet_pton (AF_INET, TEST_IP, web));
338   rd.data_size = sizeof(struct in_addr);
339   rd.data = web;
340   rd.record_type = GNUNET_GNS_RECORD_A;
341   rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
342
343   GNUNET_NAMESTORE_record_create (nh[0], key, "www", &rd, NULL, NULL);
344
345   rd.data_size = strlen(TEST_DAVE_PSEU);
346   rd.data = TEST_DAVE_PSEU;
347   rd.record_type = GNUNET_GNS_RECORD_PSEU;
348
349   GNUNET_NAMESTORE_record_create (nh[0], key, "+", &rd, &cont_ns, nh[0]);
350
351   GNUNET_CRYPTO_rsa_key_free(key);
352   GNUNET_free(keyfile);
353   GNUNET_free(web);
354   dave_is_setup = GNUNET_YES;
355   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up dave done\n");
356   return GNUNET_OK;
357 }
358
359 static int
360 setup_bob (const struct GNUNET_CONFIGURATION_Handle * cfg)
361 {
362   char* keyfile;
363   struct GNUNET_CRYPTO_RsaPrivateKey *key;
364   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
365   struct GNUNET_NAMESTORE_RecordData rd;
366
367   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up bob\n");
368   cfg_handles[1] = GNUNET_CONFIGURATION_dup (cfg);
369   GNUNET_assert (NULL != cfg_handles[1]);
370   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
371                                                             "ZONEKEY",
372                                                             &keyfile))
373   {
374     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
375     return GNUNET_SYSERR;
376   }
377
378   key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
379   if (NULL == key)
380   {
381
382     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
383     GNUNET_free (keyfile);
384     return GNUNET_SYSERR;
385   }
386
387   nh[1] = GNUNET_NAMESTORE_connect (cfg_handles[1]);
388   if (NULL == nh[1])
389   {
390     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to namestore\n");
391     GNUNET_CRYPTO_rsa_key_free (key);
392     GNUNET_free (keyfile);
393     return GNUNET_SYSERR;
394   }
395   
396   GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
397   GNUNET_CRYPTO_short_hash(&pkey, sizeof(pkey), &bob_hash);
398
399   rd.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode);
400   rd.data = &dave_hash;
401   rd.record_type = GNUNET_GNS_RECORD_PKEY;
402   rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
403
404   GNUNET_NAMESTORE_record_create (nh[1], key, "buddy", &rd, &cont_ns, nh[1]);
405
406   GNUNET_CRYPTO_rsa_key_free(key);
407   GNUNET_free(keyfile);
408   bob_is_setup = GNUNET_YES;
409   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up bob done\n");
410   return GNUNET_OK;
411 }
412
413 static int
414 setup_alice (const struct GNUNET_CONFIGURATION_Handle * cfg)
415 {
416   char* keyfile;
417   struct GNUNET_CRYPTO_RsaPrivateKey *key;
418   struct GNUNET_NAMESTORE_RecordData rd;
419
420   cfg_handles[2] = GNUNET_CONFIGURATION_dup (cfg);
421   GNUNET_assert (NULL != cfg);
422   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
423                                                             "ZONEKEY",
424                                                             &keyfile))
425   {
426     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
427     return GNUNET_SYSERR;
428   }
429
430   key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
431   if (NULL == key)
432   {
433
434     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
435     GNUNET_free (keyfile);
436     return GNUNET_SYSERR;
437   }
438
439   nh[2] = GNUNET_NAMESTORE_connect (cfg_handles[2]);
440   if (NULL == nh[2])
441   {
442     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to namestore\n");
443     GNUNET_CRYPTO_rsa_key_free (key);
444     GNUNET_free (keyfile);
445     return GNUNET_SYSERR;
446   }
447
448   rd.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode);
449   rd.data = &bob_hash;
450   rd.record_type = GNUNET_GNS_RECORD_PKEY;
451   rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
452
453   GNUNET_NAMESTORE_record_create (nh[2], key, "bob", &rd, &cont_ns, nh[2]);
454
455   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up alice gns\n");
456   gh = GNUNET_GNS_connect (cfg_handles[2]);
457   if (NULL == gh)
458   {
459     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to gns\n");
460     GNUNET_CRYPTO_rsa_key_free (key);
461     GNUNET_free (keyfile);
462     return GNUNET_SYSERR;
463   }
464
465   GNUNET_CRYPTO_rsa_key_free (key);
466   GNUNET_free (keyfile);
467   alice_is_setup = GNUNET_YES;
468   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up alice  done\n");
469   return GNUNET_OK;
470 }
471
472 static void
473 end_badly_now ()
474 {
475   if (GNUNET_SCHEDULER_NO_TASK != die_task)
476     GNUNET_SCHEDULER_cancel (die_task);
477   die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
478 }
479
480
481 /**
482  * Callback to be called when the requested peer information is available
483  *
484  * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information()
485  * @param op the operation this callback corresponds to
486  * @param pinfo the result; will be NULL if the operation has failed
487  * @param emsg error message if the operation has failed; will be NULL if the
488  *          operation is successfull
489  */
490 static void 
491 peerinfo_cb (void *cb_cls, struct GNUNET_TESTBED_Operation *op,
492              const struct GNUNET_TESTBED_PeerInformation *pinfo,
493              const char *emsg)
494 {
495   int res;
496 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "X \n");
497   GNUNET_assert (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit);
498   if (GNUNET_NO == dave_is_setup)
499     res = setup_dave (pinfo->result.cfg);
500   else if (GNUNET_NO == bob_is_setup)
501     res = setup_bob (pinfo->result.cfg);
502   else
503     res = setup_alice (pinfo->result.cfg);
504   
505   GNUNET_TESTBED_operation_done (op);
506   op = NULL;
507   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "A \n");
508   if (GNUNET_SYSERR == res)
509   {
510     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to setup peer \n");
511     end_badly_now();
512   }
513   else
514     connect_peers ();
515   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "B \n");
516   /*if (get_cfg_ops[0] == op)
517   {
518     GNUNET_assert (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit);
519     res = setup_dave (pinfo->result.cfg);
520     GNUNET_TESTBED_operation_done (get_cfg_ops[0]);
521     get_cfg_ops[0] = NULL;
522     if (GNUNET_SYSERR == res)
523     {
524       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to setup dave \n");
525       end_badly_now();
526     }
527     else
528     {
529       connect_peers ();
530     }
531   }
532   else if (get_cfg_ops[1] == op)
533   {
534     GNUNET_assert (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit);
535     res = setup_bob (pinfo->result.cfg);
536     GNUNET_TESTBED_operation_done (get_cfg_ops[1]);
537     get_cfg_ops[1] = NULL;
538     if (GNUNET_SYSERR == res)
539     {
540       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to setup dave \n");
541       end_badly_now();
542     }
543     else
544     {
545       connect_peers ();
546     }
547   }
548   else if (get_cfg_ops[2] == op)
549   {
550     GNUNET_assert (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit);
551     res = setup_alice (pinfo->result.cfg);
552     GNUNET_TESTBED_operation_done (get_cfg_ops[2]);
553     get_cfg_ops[2] = NULL;
554     if (GNUNET_SYSERR == res)
555     {
556       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to setup dave \n");
557       end_badly_now();
558     }
559     else
560     {
561       connect_peers ();
562     }
563   }*/
564 }
565
566
567 void testbed_master (void *cls,
568                      unsigned int num_peers,
569                      struct GNUNET_TESTBED_Peer **peers)
570 {
571   GNUNET_assert (NULL != peers);
572   cpeers = peers;
573
574   /* peer 0: dave */
575   GNUNET_assert (NULL != peers[0]);
576   get_cfg_ops[0] = GNUNET_TESTBED_peer_get_information (peers[0],
577                                                         GNUNET_TESTBED_PIT_CONFIGURATION,
578                                                         &peerinfo_cb, NULL);
579
580   /* peer 1: bob */
581   GNUNET_assert (NULL != peers[1]);
582   get_cfg_ops[1] = GNUNET_TESTBED_peer_get_information (peers[1],
583                                                         GNUNET_TESTBED_PIT_CONFIGURATION,
584                                                         &peerinfo_cb, NULL );
585
586   /* peer 2: alice */
587   GNUNET_assert (NULL != peers[2]);
588   get_cfg_ops[2] = GNUNET_TESTBED_peer_get_information (peers[2],
589                                                         GNUNET_TESTBED_PIT_CONFIGURATION,
590                                                         &peerinfo_cb, NULL);
591
592 }
593
594 void testbed_controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
595 {
596   static int connections = 0;
597
598   switch (event->type)
599   {
600     case GNUNET_TESTBED_ET_OPERATION_FINISHED:
601       /* This part will still be called when
602          GNUNET_TESTBED_peer_get_information() succeeds. However, the code is
603          now more relevant in operation completion callback */
604       break;
605     case GNUNET_TESTBED_ET_CONNECT:
606       connections ++;
607       if (connections == 3)
608       {
609           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers connected\n");
610           GNUNET_TESTBED_operation_done (connect_ops[0]);
611           connect_ops[0] = NULL;
612           GNUNET_TESTBED_operation_done (connect_ops[1]);
613           connect_ops[1] = NULL;
614           GNUNET_TESTBED_operation_done (connect_ops[2]);
615           connect_ops[2] = NULL;
616           all_connected ();
617       }
618       break;
619     default:
620       /* whatever ... */
621       break;
622   }
623 }
624
625 int
626 main (int argc, char *argv[])
627 {
628   uint64_t event_mask;
629   ok = 0;
630   event_mask = 0;
631   event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT);
632   event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED);
633   GNUNET_TESTBED_test_run ("test_gns_dht_three_peers", "test_gns_dht_default.conf",
634                            3, event_mask,
635                            &testbed_controller_cb, NULL,
636                            &testbed_master, NULL);
637   if (GNUNET_SYSERR == ok)
638     return 1;
639   return 0;
640 }
641
642 /* end of test_gns_dht_three_peers.c */
643