-fix to api
[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, 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.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_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 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "C \n");
277   if (3 == started)
278   {
279       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers started\n");
280
281       connect_ops[0] = GNUNET_TESTBED_overlay_connect (NULL, NULL, NULL,
282                                                        cpeers[0],
283                                                        cpeers[1]);
284
285       connect_ops[1] = GNUNET_TESTBED_overlay_connect (NULL, NULL, NULL,
286                                                        cpeers[1],
287                                                        cpeers[2]);
288
289       connect_ops[2] = GNUNET_TESTBED_overlay_connect (NULL, NULL, NULL,
290                                                        cpeers[0],
291                                                        cpeers[2]);
292   }
293 }
294
295 static int
296 setup_dave (const struct GNUNET_CONFIGURATION_Handle * cfg)
297 {
298   char* keyfile;
299   struct GNUNET_CRYPTO_RsaPrivateKey *key;
300   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
301   struct in_addr *web;
302   struct GNUNET_NAMESTORE_RecordData rd;
303
304   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up dave\n");
305   cfg_handles[0] = GNUNET_CONFIGURATION_dup (cfg);
306   GNUNET_assert (NULL != cfg_handles[0]);
307   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
308                                                             "ZONEKEY",
309                                                             &keyfile))
310   {
311     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
312     return GNUNET_SYSERR;
313   }
314
315   key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
316   if (NULL == key)
317   {
318
319     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
320     GNUNET_free (keyfile);
321     return GNUNET_SYSERR;
322   }
323   nh[0] = GNUNET_NAMESTORE_connect (cfg_handles[0]);
324   if (NULL == nh[0])
325   {
326     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to namestore\n");
327     GNUNET_CRYPTO_rsa_key_free (key);
328     GNUNET_free (keyfile);
329     return GNUNET_SYSERR;
330   }
331
332   GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
333   GNUNET_CRYPTO_short_hash(&pkey, sizeof(pkey), &dave_hash);
334
335   web = GNUNET_malloc(sizeof(struct in_addr));
336   GNUNET_assert(1 == inet_pton (AF_INET, TEST_IP, web));
337   rd.data_size = sizeof(struct in_addr);
338   rd.data = web;
339   rd.record_type = GNUNET_GNS_RECORD_A;
340   rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
341
342   GNUNET_NAMESTORE_record_create (nh[0], key, "www", &rd, NULL, NULL);
343
344   rd.data_size = strlen(TEST_DAVE_PSEU);
345   rd.data = TEST_DAVE_PSEU;
346   rd.record_type = GNUNET_GNS_RECORD_PSEU;
347
348   GNUNET_NAMESTORE_record_create (nh[0], key, "+", &rd, &cont_ns, nh[0]);
349
350   GNUNET_CRYPTO_rsa_key_free(key);
351   GNUNET_free(keyfile);
352   GNUNET_free(web);
353   dave_is_setup = GNUNET_YES;
354   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up dave done\n");
355   return GNUNET_OK;
356 }
357
358 static int
359 setup_bob (const struct GNUNET_CONFIGURATION_Handle * cfg)
360 {
361   char* keyfile;
362   struct GNUNET_CRYPTO_RsaPrivateKey *key;
363   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
364   struct GNUNET_NAMESTORE_RecordData rd;
365
366   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up bob\n");
367   cfg_handles[1] = GNUNET_CONFIGURATION_dup (cfg);
368   GNUNET_assert (NULL != cfg_handles[1]);
369   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
370                                                             "ZONEKEY",
371                                                             &keyfile))
372   {
373     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
374     return GNUNET_SYSERR;
375   }
376
377   key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
378   if (NULL == key)
379   {
380
381     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
382     GNUNET_free (keyfile);
383     return GNUNET_SYSERR;
384   }
385
386   nh[1] = GNUNET_NAMESTORE_connect (cfg_handles[1]);
387   if (NULL == nh[1])
388   {
389     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to namestore\n");
390     GNUNET_CRYPTO_rsa_key_free (key);
391     GNUNET_free (keyfile);
392     return GNUNET_SYSERR;
393   }
394   
395   GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
396   GNUNET_CRYPTO_short_hash(&pkey, sizeof(pkey), &bob_hash);
397
398   rd.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode);
399   rd.data = &dave_hash;
400   rd.record_type = GNUNET_GNS_RECORD_PKEY;
401   rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
402
403   GNUNET_NAMESTORE_record_create (nh[1], key, "buddy", &rd, &cont_ns, nh[1]);
404
405   GNUNET_CRYPTO_rsa_key_free(key);
406   GNUNET_free(keyfile);
407   bob_is_setup = GNUNET_YES;
408   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up bob done\n");
409   return GNUNET_OK;
410 }
411
412 static int
413 setup_alice (const struct GNUNET_CONFIGURATION_Handle * cfg)
414 {
415   char* keyfile;
416   struct GNUNET_CRYPTO_RsaPrivateKey *key;
417   struct GNUNET_NAMESTORE_RecordData rd;
418
419   cfg_handles[2] = GNUNET_CONFIGURATION_dup (cfg);
420   GNUNET_assert (NULL != cfg);
421   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
422                                                             "ZONEKEY",
423                                                             &keyfile))
424   {
425     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
426     return GNUNET_SYSERR;
427   }
428
429   key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
430   if (NULL == key)
431   {
432
433     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
434     GNUNET_free (keyfile);
435     return GNUNET_SYSERR;
436   }
437
438   nh[2] = GNUNET_NAMESTORE_connect (cfg_handles[2]);
439   if (NULL == nh[2])
440   {
441     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to namestore\n");
442     GNUNET_CRYPTO_rsa_key_free (key);
443     GNUNET_free (keyfile);
444     return GNUNET_SYSERR;
445   }
446
447   rd.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode);
448   rd.data = &bob_hash;
449   rd.record_type = GNUNET_GNS_RECORD_PKEY;
450   rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
451
452   GNUNET_NAMESTORE_record_create (nh[2], key, "bob", &rd, &cont_ns, nh[2]);
453
454   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up alice gns\n");
455   gh = GNUNET_GNS_connect (cfg_handles[2]);
456   if (NULL == gh)
457   {
458     GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to gns\n");
459     GNUNET_CRYPTO_rsa_key_free (key);
460     GNUNET_free (keyfile);
461     return GNUNET_SYSERR;
462   }
463
464   GNUNET_CRYPTO_rsa_key_free (key);
465   GNUNET_free (keyfile);
466   alice_is_setup = GNUNET_YES;
467   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up alice  done\n");
468   return GNUNET_OK;
469 }
470
471 static void
472 end_badly_now ()
473 {
474   if (GNUNET_SCHEDULER_NO_TASK != die_task)
475     GNUNET_SCHEDULER_cancel (die_task);
476   die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
477 }
478
479
480 /**
481  * Callback to be called when the requested peer information is available
482  *
483  * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information()
484  * @param op the operation this callback corresponds to
485  * @param pinfo the result; will be NULL if the operation has failed
486  * @param emsg error message if the operation has failed; will be NULL if the
487  *          operation is successfull
488  */
489 static void 
490 peerinfo_cb (void *cb_cls, struct GNUNET_TESTBED_Operation *op,
491              const struct GNUNET_TESTBED_PeerInformation *pinfo,
492              const char *emsg)
493 {
494   int res;
495 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "X \n");
496   GNUNET_assert (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit);
497   if (GNUNET_NO == dave_is_setup)
498     res = setup_dave (pinfo->result.cfg);
499   else if (GNUNET_NO == bob_is_setup)
500     res = setup_bob (pinfo->result.cfg);
501   else
502     res = setup_alice (pinfo->result.cfg);
503   
504   if (get_cfg_ops[0] == op)
505     get_cfg_ops[0] = NULL;
506   else if (get_cfg_ops[1] == op)
507     get_cfg_ops[1] = NULL;
508   else
509     get_cfg_ops[2] = NULL;
510   GNUNET_TESTBED_operation_done (op);
511   op = NULL;
512   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "A \n");
513   if (GNUNET_SYSERR == res)
514   {
515     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to setup peer \n");
516     end_badly_now();
517   }
518   else
519     connect_peers ();
520   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "B \n");
521   /*if (get_cfg_ops[0] == op)
522   {
523     GNUNET_assert (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit);
524     res = setup_dave (pinfo->result.cfg);
525     GNUNET_TESTBED_operation_done (get_cfg_ops[0]);
526     get_cfg_ops[0] = NULL;
527     if (GNUNET_SYSERR == res)
528     {
529       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to setup dave \n");
530       end_badly_now();
531     }
532     else
533     {
534       connect_peers ();
535     }
536   }
537   else if (get_cfg_ops[1] == op)
538   {
539     GNUNET_assert (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit);
540     res = setup_bob (pinfo->result.cfg);
541     GNUNET_TESTBED_operation_done (get_cfg_ops[1]);
542     get_cfg_ops[1] = NULL;
543     if (GNUNET_SYSERR == res)
544     {
545       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to setup dave \n");
546       end_badly_now();
547     }
548     else
549     {
550       connect_peers ();
551     }
552   }
553   else if (get_cfg_ops[2] == op)
554   {
555     GNUNET_assert (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit);
556     res = setup_alice (pinfo->result.cfg);
557     GNUNET_TESTBED_operation_done (get_cfg_ops[2]);
558     get_cfg_ops[2] = NULL;
559     if (GNUNET_SYSERR == res)
560     {
561       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to setup dave \n");
562       end_badly_now();
563     }
564     else
565     {
566       connect_peers ();
567     }
568   }*/
569 }
570
571
572 void testbed_master (void *cls,
573                      unsigned int num_peers,
574                      struct GNUNET_TESTBED_Peer **peers)
575 {
576   GNUNET_assert (NULL != peers);
577   cpeers = peers;
578
579   /* peer 0: dave */
580   GNUNET_assert (NULL != peers[0]);
581   get_cfg_ops[0] = GNUNET_TESTBED_peer_get_information (peers[0],
582                                                         GNUNET_TESTBED_PIT_CONFIGURATION,
583                                                         &peerinfo_cb, NULL);
584
585   /* peer 1: bob */
586   GNUNET_assert (NULL != peers[1]);
587   get_cfg_ops[1] = GNUNET_TESTBED_peer_get_information (peers[1],
588                                                         GNUNET_TESTBED_PIT_CONFIGURATION,
589                                                         &peerinfo_cb, NULL );
590
591   /* peer 2: alice */
592   GNUNET_assert (NULL != peers[2]);
593   get_cfg_ops[2] = GNUNET_TESTBED_peer_get_information (peers[2],
594                                                         GNUNET_TESTBED_PIT_CONFIGURATION,
595                                                         &peerinfo_cb, NULL);
596
597 }
598
599 void testbed_controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
600 {
601   static int connections = 0;
602
603   switch (event->type)
604   {
605     case GNUNET_TESTBED_ET_OPERATION_FINISHED:
606       /* This part will still be called when
607          GNUNET_TESTBED_peer_get_information() succeeds. However, the code is
608          now more relevant in operation completion callback */
609       break;
610     case GNUNET_TESTBED_ET_CONNECT:
611       connections ++;
612       if (connections == 3)
613       {
614           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers connected\n");
615           GNUNET_TESTBED_operation_done (connect_ops[0]);
616           connect_ops[0] = NULL;
617           GNUNET_TESTBED_operation_done (connect_ops[1]);
618           connect_ops[1] = NULL;
619           GNUNET_TESTBED_operation_done (connect_ops[2]);
620           connect_ops[2] = NULL;
621           all_connected ();
622       }
623       break;
624     default:
625       /* whatever ... */
626       break;
627   }
628 }
629
630 int
631 main (int argc, char *argv[])
632 {
633   uint64_t event_mask;
634   ok = 0;
635   event_mask = 0;
636   event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT);
637   event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED);
638   GNUNET_TESTBED_test_run ("test_gns_dht_three_peers", "test_gns_dht_default.conf",
639                            3, event_mask,
640                            &testbed_controller_cb, NULL,
641                            &testbed_master, NULL);
642   if (GNUNET_SYSERR == ok)
643     return 1;
644   return 0;
645 }
646
647 /* end of test_gns_dht_three_peers.c */
648