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