-fix
[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.gads
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, 10)
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.gads"
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_SCHEDULER_shutdown ();
138   ok = 1;
139 }
140
141 static void
142 end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
143 {
144   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Finished\n");
145   int c;
146   if (GNUNET_SCHEDULER_NO_TASK != die_task)
147   {
148       GNUNET_SCHEDULER_cancel (die_task);
149       die_task = GNUNET_SCHEDULER_NO_TASK;
150   }
151
152   for (c = 0; c < 3; c++)
153   {
154     if (NULL != nh[c])
155     {
156       GNUNET_NAMESTORE_disconnect(nh[c]);
157       nh[c] = NULL;
158     }
159     if (NULL != cfg_handles[c])
160     {
161       GNUNET_CONFIGURATION_destroy (cfg_handles[c]);
162       cfg_handles[c] = NULL;
163     }
164   }
165
166   if (NULL != gh)
167   {
168     GNUNET_GNS_disconnect(gh);
169     gh = NULL;
170   }
171
172   if (0 == ok)
173     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test ended successful\n");
174   else
175     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test failed\n");
176   GNUNET_SCHEDULER_shutdown ();
177 }
178
179 static void
180 end_now ()
181 {
182   GNUNET_SCHEDULER_add_now (&end, NULL);
183 }
184
185
186 static void
187 disconnect_ns (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
188 {
189
190   GNUNET_NAMESTORE_disconnect (cls);
191   if (cls == nh[0])
192     nh[0] = NULL;
193   if (cls == nh[1])
194     nh[1] = NULL;
195   if (cls == nh[2])
196     nh[2] = NULL;
197 }
198
199
200 static void
201 cont_ns (void* cls, int32_t s, const char* emsg)
202 {
203   GNUNET_SCHEDULER_add_now (&disconnect_ns, cls);
204 }
205
206 static void
207 on_lookup_result(void *cls, uint32_t rd_count,
208                  const struct GNUNET_NAMESTORE_RecordData *rd)
209 {
210   int i;
211   char* string_val;
212
213   if (rd_count == 0)
214   {
215     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
216                 "Lookup failed!\n");
217     ok = 2;
218   }
219   else
220   {
221     ok = 1;
222     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls);
223     for (i=0; i<rd_count; i++)
224     {
225       string_val = GNUNET_NAMESTORE_value_to_string(rd[i].record_type,
226                                                     rd[i].data,
227                                                     rd[i].data_size);
228       if (0 == strcmp(string_val, TEST_IP))
229       {
230         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
231                     "%s correctly resolved to %s!\n", TEST_DOMAIN, string_val);
232         ok = 0;
233       }
234       GNUNET_free (string_val);
235     }
236   }
237   end_now ();
238 }
239
240 static void
241 commence_testing(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
242 {
243   static int wait = 0;
244   wait++;
245   if ((ZONE_PUT_WAIT_TIME.rel_value / 1000) == wait)
246   {
247     fprintf (stderr, "\n");
248     wait_task = GNUNET_SCHEDULER_NO_TASK;
249     lookup_handle = GNUNET_GNS_lookup(gh, TEST_DOMAIN, GNUNET_GNS_RECORD_A,
250                       GNUNET_NO,
251                       NULL,
252                       &on_lookup_result, TEST_DOMAIN);
253     if (GNUNET_SCHEDULER_NO_TASK != die_task)
254       GNUNET_SCHEDULER_cancel(die_task);
255     die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, "from lookup");
256   }
257   else
258   {
259       fprintf (stderr, ".");
260       wait_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &commence_testing, NULL);
261   }
262 }
263
264 void
265 all_connected ()
266 {
267   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Created all connections! Waiting for PUTs\n");
268   wait_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &commence_testing, NULL);
269 }
270
271
272 static void connect_peers ()
273 {
274   static int started;
275   started ++;
276   if (3 == started)
277   {
278       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers started\n");
279
280       connect_ops[0] = GNUNET_TESTBED_overlay_connect (NULL, NULL, NULL,
281                                                        cpeers[0],
282                                                        cpeers[1]);
283
284       connect_ops[1] = GNUNET_TESTBED_overlay_connect (NULL, NULL, NULL,
285                                                        cpeers[1],
286                                                        cpeers[2]);
287
288       connect_ops[2] = GNUNET_TESTBED_overlay_connect (NULL, NULL, NULL,
289                                                        cpeers[0],
290                                                        cpeers[2]);
291   }
292 }
293
294 static int
295 setup_dave (const struct GNUNET_CONFIGURATION_Handle * cfg)
296 {
297   char* keyfile;
298   struct GNUNET_CRYPTO_RsaPrivateKey *key;
299   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
300   struct in_addr *web;
301   struct GNUNET_NAMESTORE_RecordData rd;
302
303   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up dave\n");
304   cfg_handles[0] = GNUNET_CONFIGURATION_dup (cfg);
305   GNUNET_assert (NULL != cfg_handles[0]);
306   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
307                                                             "ZONEKEY",
308                                                             &keyfile))
309   {
310     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
311     return GNUNET_SYSERR;
312   }
313
314   key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
315   if (NULL == key)
316   {
317
318     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
319     GNUNET_free (keyfile);
320     return GNUNET_SYSERR;
321   }
322   nh[0] = GNUNET_NAMESTORE_connect (cfg_handles[0]);
323   if (NULL == nh[0])
324   {
325     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to namestore\n");
326     GNUNET_CRYPTO_rsa_key_free (key);
327     GNUNET_free (keyfile);
328     return GNUNET_SYSERR;
329   }
330
331   GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
332   GNUNET_CRYPTO_short_hash(&pkey, sizeof(pkey), &dave_hash);
333
334   rd.expiration_time = UINT64_MAX;
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
350   GNUNET_NAMESTORE_record_create (nh[0], key, "+", &rd, &cont_ns, nh[0]);
351
352   GNUNET_CRYPTO_rsa_key_free(key);
353   GNUNET_free(keyfile);
354   GNUNET_free(web);
355   dave_is_setup = GNUNET_YES;
356   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up dave done\n");
357   return GNUNET_OK;
358 }
359
360 static int
361 setup_bob (const struct GNUNET_CONFIGURATION_Handle * cfg)
362 {
363   char* keyfile;
364   struct GNUNET_CRYPTO_RsaPrivateKey *key;
365   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
366   struct GNUNET_NAMESTORE_RecordData rd;
367
368   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up bob\n");
369   cfg_handles[1] = GNUNET_CONFIGURATION_dup (cfg);
370   GNUNET_assert (NULL != cfg_handles[1]);
371   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
372                                                             "ZONEKEY",
373                                                             &keyfile))
374   {
375     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
376     return GNUNET_SYSERR;
377   }
378
379   key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
380   if (NULL == key)
381   {
382
383     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
384     GNUNET_free (keyfile);
385     return GNUNET_SYSERR;
386   }
387
388   nh[1] = GNUNET_NAMESTORE_connect (cfg_handles[1]);
389   if (NULL == nh[1])
390   {
391     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to namestore\n");
392     GNUNET_CRYPTO_rsa_key_free (key);
393     GNUNET_free (keyfile);
394     return GNUNET_SYSERR;
395   }
396   
397   GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
398   GNUNET_CRYPTO_short_hash(&pkey, sizeof(pkey), &bob_hash);
399
400   rd.expiration_time = UINT64_MAX;
401   rd.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode);
402   rd.data = &dave_hash;
403   rd.record_type = GNUNET_GNS_RECORD_PKEY;
404   rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
405
406   GNUNET_NAMESTORE_record_create (nh[1], key, "buddy", &rd, &cont_ns, nh[1]);
407
408   GNUNET_CRYPTO_rsa_key_free(key);
409   GNUNET_free(keyfile);
410   bob_is_setup = GNUNET_YES;
411   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up bob done\n");
412   return GNUNET_OK;
413 }
414
415 static int
416 setup_alice (const struct GNUNET_CONFIGURATION_Handle * cfg)
417 {
418   char* keyfile;
419   struct GNUNET_CRYPTO_RsaPrivateKey *key;
420   struct GNUNET_NAMESTORE_RecordData rd;
421
422   cfg_handles[2] = GNUNET_CONFIGURATION_dup (cfg);
423   GNUNET_assert (NULL != cfg);
424   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
425                                                             "ZONEKEY",
426                                                             &keyfile))
427   {
428     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
429     return GNUNET_SYSERR;
430   }
431
432   key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
433   if (NULL == key)
434   {
435
436     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
437     GNUNET_free (keyfile);
438     return GNUNET_SYSERR;
439   }
440
441   nh[2] = GNUNET_NAMESTORE_connect (cfg_handles[2]);
442   if (NULL == nh[2])
443   {
444     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to namestore\n");
445     GNUNET_CRYPTO_rsa_key_free (key);
446     GNUNET_free (keyfile);
447     return GNUNET_SYSERR;
448   }
449
450   rd.expiration_time = UINT64_MAX;
451   rd.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode);
452   rd.data = &bob_hash;
453   rd.record_type = GNUNET_GNS_RECORD_PKEY;
454   rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
455
456   GNUNET_NAMESTORE_record_create (nh[2], key, "bob", &rd, &cont_ns, nh[2]);
457
458   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up alice gns\n");
459   gh = GNUNET_GNS_connect (cfg_handles[2]);
460   if (NULL == gh)
461   {
462     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to gns\n");
463     GNUNET_CRYPTO_rsa_key_free (key);
464     GNUNET_free (keyfile);
465     return GNUNET_SYSERR;
466   }
467
468   GNUNET_CRYPTO_rsa_key_free (key);
469   GNUNET_free (keyfile);
470   alice_is_setup = GNUNET_YES;
471   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up alice  done\n");
472   return GNUNET_OK;
473 }
474
475 static void
476 end_badly_now ()
477 {
478   if (GNUNET_SCHEDULER_NO_TASK != die_task)
479     GNUNET_SCHEDULER_cancel (die_task);
480   die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
481 }
482
483
484 /**
485  * Callback to be called when the requested peer information is available
486  *
487  * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information()
488  * @param op the operation this callback corresponds to
489  * @param pinfo the result; will be NULL if the operation has failed
490  * @param emsg error message if the operation has failed; will be NULL if the
491  *          operation is successfull
492  */
493 static void 
494 peerinfo_cb (void *cb_cls, struct GNUNET_TESTBED_Operation *op,
495              const struct GNUNET_TESTBED_PeerInformation *pinfo,
496              const char *emsg)
497 {
498   int res;
499   GNUNET_assert (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit);
500   if (GNUNET_NO == dave_is_setup)
501     res = setup_dave (pinfo->result.cfg);
502   else if (GNUNET_NO == bob_is_setup)
503     res = setup_bob (pinfo->result.cfg);
504   else
505     res = setup_alice (pinfo->result.cfg);
506   
507   if (get_cfg_ops[0] == op)
508     get_cfg_ops[0] = NULL;
509   else if (get_cfg_ops[1] == op)
510     get_cfg_ops[1] = NULL;
511   else
512     get_cfg_ops[2] = NULL;
513   GNUNET_TESTBED_operation_done (op);
514   op = NULL;
515   if (GNUNET_SYSERR == res)
516   {
517     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to setup peer \n");
518     end_badly_now();
519   }
520   else
521     connect_peers ();
522   /*if (get_cfg_ops[0] == op)
523   {
524     GNUNET_assert (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit);
525     res = setup_dave (pinfo->result.cfg);
526     GNUNET_TESTBED_operation_done (get_cfg_ops[0]);
527     get_cfg_ops[0] = NULL;
528     if (GNUNET_SYSERR == res)
529     {
530       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to setup dave \n");
531       end_badly_now();
532     }
533     else
534     {
535       connect_peers ();
536     }
537   }
538   else if (get_cfg_ops[1] == op)
539   {
540     GNUNET_assert (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit);
541     res = setup_bob (pinfo->result.cfg);
542     GNUNET_TESTBED_operation_done (get_cfg_ops[1]);
543     get_cfg_ops[1] = NULL;
544     if (GNUNET_SYSERR == res)
545     {
546       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to setup dave \n");
547       end_badly_now();
548     }
549     else
550     {
551       connect_peers ();
552     }
553   }
554   else if (get_cfg_ops[2] == op)
555   {
556     GNUNET_assert (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit);
557     res = setup_alice (pinfo->result.cfg);
558     GNUNET_TESTBED_operation_done (get_cfg_ops[2]);
559     get_cfg_ops[2] = NULL;
560     if (GNUNET_SYSERR == res)
561     {
562       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to setup dave \n");
563       end_badly_now();
564     }
565     else
566     {
567       connect_peers ();
568     }
569   }*/
570 }
571
572
573 void testbed_master (void *cls,
574                      unsigned int num_peers,
575                      struct GNUNET_TESTBED_Peer **peers)
576 {
577   GNUNET_assert (NULL != peers);
578   cpeers = peers;
579
580   /* peer 0: dave */
581   GNUNET_assert (NULL != peers[0]);
582   get_cfg_ops[0] = GNUNET_TESTBED_peer_get_information (peers[0],
583                                                         GNUNET_TESTBED_PIT_CONFIGURATION,
584                                                         &peerinfo_cb, NULL);
585
586   /* peer 1: bob */
587   GNUNET_assert (NULL != peers[1]);
588   get_cfg_ops[1] = GNUNET_TESTBED_peer_get_information (peers[1],
589                                                         GNUNET_TESTBED_PIT_CONFIGURATION,
590                                                         &peerinfo_cb, NULL );
591
592   /* peer 2: alice */
593   GNUNET_assert (NULL != peers[2]);
594   get_cfg_ops[2] = GNUNET_TESTBED_peer_get_information (peers[2],
595                                                         GNUNET_TESTBED_PIT_CONFIGURATION,
596                                                         &peerinfo_cb, NULL);
597
598 }
599
600 void testbed_controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
601 {
602   static int connections = 0;
603
604   switch (event->type)
605   {
606     case GNUNET_TESTBED_ET_OPERATION_FINISHED:
607       /* This part will still be called when
608          GNUNET_TESTBED_peer_get_information() succeeds. However, the code is
609          now more relevant in operation completion callback */
610       break;
611     case GNUNET_TESTBED_ET_CONNECT:
612       connections ++;
613       if (connections == 3)
614       {
615           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers connected\n");
616           GNUNET_TESTBED_operation_done (connect_ops[0]);
617           connect_ops[0] = NULL;
618           GNUNET_TESTBED_operation_done (connect_ops[1]);
619           connect_ops[1] = NULL;
620           GNUNET_TESTBED_operation_done (connect_ops[2]);
621           connect_ops[2] = NULL;
622           all_connected ();
623       }
624       break;
625     default:
626       /* whatever ... */
627       break;
628   }
629 }
630
631 int
632 main (int argc, char *argv[])
633 {
634   uint64_t event_mask;
635   ok = 0;
636   event_mask = 0;
637   event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT);
638   event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED);
639   GNUNET_TESTBED_test_run ("test_gns_dht_three_peers", "test_gns_dht_default.conf",
640                            3, event_mask,
641                            &testbed_controller_cb, NULL,
642                            &testbed_master, NULL);
643   if (GNUNET_SYSERR == ok)
644     return 1;
645   return 0;
646 }
647
648 /* end of test_gns_dht_three_peers.c */
649