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