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