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