aboutsummaryrefslogtreecommitdiff
path: root/src/transport/transport-testing2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/transport-testing2.c')
-rw-r--r--src/transport/transport-testing2.c930
1 files changed, 0 insertions, 930 deletions
diff --git a/src/transport/transport-testing2.c b/src/transport/transport-testing2.c
deleted file mode 100644
index ec27ac8ba..000000000
--- a/src/transport/transport-testing2.c
+++ /dev/null
@@ -1,930 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2006, 2009, 2015, 2016 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file transport-testing.c
22 * @brief testing lib for transport service
23 * @author Matthias Wachs
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "transport-testing2.h"
28
29
30#define LOG(kind, ...) GNUNET_log_from (kind, "transport-testing", __VA_ARGS__)
31
32
33static struct GNUNET_TRANSPORT_TESTING_PeerContext *
34find_peer_context (struct GNUNET_TRANSPORT_TESTING_Handle *tth,
35 const struct GNUNET_PeerIdentity *peer)
36{
37 struct GNUNET_TRANSPORT_TESTING_PeerContext *t;
38
39 for (t = tth->p_head; NULL != t; t = t->next)
40 if (0 == memcmp (&t->id,
41 peer,
42 sizeof(struct GNUNET_PeerIdentity)))
43 return t;
44 return NULL;
45}
46
47
48/**
49 * Find any connecting context matching the given pair of peers.
50 *
51 * @param p1 first peer
52 * @param p2 second peer
53 * @param cb function to call
54 * @param cb_cls closure for @a cb
55 */
56void
57GNUNET_TRANSPORT_TESTING_find_connecting_context (struct
58 GNUNET_TRANSPORT_TESTING_PeerContext
59 *p1,
60 struct
61 GNUNET_TRANSPORT_TESTING_PeerContext
62 *p2,
63 GNUNET_TRANSPORT_TESTING_ConnectContextCallback
64 cb,
65 void *cb_cls)
66{
67 struct GNUNET_TRANSPORT_TESTING_Handle *tth = p1->tth;
68 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
69 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn;
70
71 for (cc = tth->cc_head; NULL != cc; cc = ccn)
72 {
73 ccn = cc->next;
74 if ((cc->p1 == p1) &&
75 (cc->p2 == p2))
76 cb (cb_cls,
77 cc);
78 }
79}
80
81
82static void
83set_p1c (void *cls,
84 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx)
85{
86 int *found = cls;
87
88 if (NULL != found)
89 *found = GNUNET_YES;
90 cx->p1_c = GNUNET_YES;
91}
92
93
94static void
95set_mq (void *cls,
96 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx)
97{
98 struct GNUNET_MQ_Handle *mq = cls;
99
100 cx->mq = mq;
101}
102
103
104static void
105set_p2c (void *cls,
106 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx)
107{
108 int *found = cls;
109
110 if (NULL != found)
111 *found = GNUNET_YES;
112 cx->p2_c = GNUNET_YES;
113}
114
115
116static void
117clear_p1c (void *cls,
118 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx)
119{
120 int *found = cls;
121
122 if (NULL != found)
123 *found = GNUNET_YES;
124 cx->p1_c = GNUNET_NO;
125}
126
127
128static void
129clear_p2c (void *cls,
130 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx)
131{
132 int *found = cls;
133
134 if (NULL != found)
135 *found = GNUNET_YES;
136 cx->p2_c = GNUNET_NO;
137}
138
139
140static void *
141notify_connect (void *cls,
142 const struct GNUNET_PeerIdentity *peer,
143 struct GNUNET_MQ_Handle *mq)
144{
145 struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
146 struct GNUNET_TRANSPORT_TESTING_Handle *tth = p->tth;
147 char *p2_s;
148 struct GNUNET_TRANSPORT_TESTING_PeerContext *p2;
149 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
150 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn;
151 int found;
152 void *ret;
153
154 p2 = find_peer_context (p->tth,
155 peer);
156 if (NULL != p->nc)
157 ret = p->nc (p->cb_cls,
158 peer,
159 mq);
160 else
161 ret = NULL;
162
163 if (NULL != p2)
164 GNUNET_asprintf (&p2_s,
165 "%u (`%s')",
166 p2->no,
167 GNUNET_i2s (&p2->id));
168 else
169 GNUNET_asprintf (&p2_s,
170 "`%s'",
171 GNUNET_i2s (peer));
172 LOG (GNUNET_ERROR_TYPE_DEBUG,
173 "Peers %s connected to peer %u (`%s')\n",
174 p2_s,
175 p->no,
176 GNUNET_i2s (&p->id));
177 GNUNET_free (p2_s);
178 /* update flags in connecting contexts */
179 found = GNUNET_NO;
180 GNUNET_TRANSPORT_TESTING_find_connecting_context (p,
181 p2,
182 &set_p1c,
183 &found);
184 if (GNUNET_NO == found)
185 {
186 cc = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_ConnectRequest);
187 cc->p1 = p;
188 cc->p2 = p2;
189 cc->p1_c = GNUNET_YES;
190 GNUNET_CONTAINER_DLL_insert (tth->cc_head,
191 tth->cc_tail,
192 cc);
193 }
194 found = GNUNET_NO;
195 GNUNET_TRANSPORT_TESTING_find_connecting_context (p2,
196 p,
197 &set_p2c,
198 &found);
199 if (GNUNET_NO == found)
200 {
201 cc = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_ConnectRequest);
202 cc->p1 = p2;
203 cc->p2 = p;
204 cc->p1_c = GNUNET_YES;
205 GNUNET_CONTAINER_DLL_insert (tth->cc_head,
206 tth->cc_tail,
207 cc);
208 }
209 GNUNET_TRANSPORT_TESTING_find_connecting_context (p,
210 p2,
211 &set_mq,
212 mq);
213 /* update set connected flag for all requests */
214 for (cc = tth->cc_head; NULL != cc; cc = cc->next)
215 {
216 if (GNUNET_YES == cc->connected)
217 continue;
218 if ((GNUNET_YES == cc->p1_c) &&
219 (GNUNET_YES == cc->p2_c))
220 {
221 cc->connected = GNUNET_YES;
222 /* stop trying to connect */
223 if (NULL != cc->tct)
224 {
225 GNUNET_SCHEDULER_cancel (cc->tct);
226 cc->tct = NULL;
227 }
228 if (NULL != cc->ats_sh)
229 {
230 GNUNET_ATS_connectivity_suggest_cancel (cc->ats_sh);
231 cc->ats_sh = NULL;
232 }
233 }
234 }
235 /* then notify application */
236 for (cc = tth->cc_head; NULL != cc; cc = ccn)
237 {
238 ccn = cc->next;
239 if ((GNUNET_YES == cc->connected) &&
240 (NULL != cc->cb))
241 {
242 cc->cb (cc->cb_cls);
243 cc->cb = NULL; /* only notify once! */
244 }
245 }
246 return ret;
247}
248
249
250/**
251 * Offer the current HELLO of P2 to P1.
252 *
253 * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectRequest`
254 */
255static void
256offer_hello (void *cls);
257
258
259static void
260notify_disconnect (void *cls,
261 const struct GNUNET_PeerIdentity *peer,
262 void *handler_cls)
263{
264 struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
265 struct GNUNET_TRANSPORT_TESTING_Handle *tth = p->tth;
266 char *p2_s;
267 /* Find PeerContext */
268 int no = 0;
269 struct GNUNET_TRANSPORT_TESTING_PeerContext *p2 = NULL;
270 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
271
272 p2 = find_peer_context (p->tth,
273 peer);
274 no = p->no;
275 if (NULL != p2)
276 GNUNET_asprintf (&p2_s,
277 "%u (`%s')",
278 p2->no,
279 GNUNET_i2s (&p2->id));
280 else
281 GNUNET_asprintf (&p2_s,
282 "`%s'",
283 GNUNET_i2s (peer));
284 LOG (GNUNET_ERROR_TYPE_DEBUG,
285 "Peers %s disconnected from peer %u (`%s')\n",
286 p2_s,
287 no,
288 GNUNET_i2s (&p->id));
289 GNUNET_free (p2_s);
290 /* notify about disconnect */
291 if (NULL != p->nd)
292 p->nd (p->cb_cls,
293 peer,
294 handler_cls);
295 if (NULL == p2)
296 return;
297 /* clear MQ, it is now invalid */
298 GNUNET_TRANSPORT_TESTING_find_connecting_context (p,
299 p2,
300 &set_mq,
301 NULL);
302 /* update set connected flags for all requests */
303 GNUNET_TRANSPORT_TESTING_find_connecting_context (p,
304 p2,
305 &clear_p1c,
306 NULL);
307 GNUNET_TRANSPORT_TESTING_find_connecting_context (p2,
308 p,
309 &clear_p2c,
310 NULL);
311 /* resume connectivity requests as necessary */
312 for (cc = tth->cc_head; NULL != cc; cc = cc->next)
313 {
314 if (GNUNET_NO == cc->connected)
315 continue;
316 if ((GNUNET_YES != cc->p1_c) ||
317 (GNUNET_YES != cc->p2_c))
318 {
319 cc->connected = GNUNET_NO;
320 /* start trying to connect */
321 if (NULL == cc->tct)
322 cc->tct = GNUNET_SCHEDULER_add_now (&offer_hello,
323 cc);
324 if (NULL == cc->ats_sh)
325 cc->ats_sh = GNUNET_ATS_connectivity_suggest (cc->p1->ats,
326 &p2->id,
327 1);
328 }
329 }
330}
331
332
333static void
334retrieve_hello (void *cls);
335
336static void
337hello_iter_cb (void *cb_cls,
338 const struct GNUNET_PEERSTORE_Record *record,
339 const char *emsg)
340{
341 struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cb_cls;
342 if (NULL == record)
343 {
344 p->pic = NULL;
345 if (NULL != p->start_cb)
346 p->rh_task = GNUNET_SCHEDULER_add_now (retrieve_hello, p);
347 return;
348 }
349 // Check record type et al?
350 p->hello_size = record->value_size;
351 p->hello = GNUNET_malloc (p->hello_size);
352 memcpy (p->hello, record->value, p->hello_size);
353 p->hello[p->hello_size - 1] = '\0';
354
355 GNUNET_PEERSTORE_iterate_cancel (p->pic);
356 p->pic = NULL;
357 if (NULL != p->start_cb)
358 {
359 LOG (GNUNET_ERROR_TYPE_DEBUG,
360 "Peer %u (`%s') successfully started\n",
361 p->no,
362 GNUNET_i2s (&p->id));
363 p->start_cb (p->start_cb_cls);
364 p->start_cb = NULL;
365 }
366}
367
368
369static void
370retrieve_hello (void *cls)
371{
372 struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
373 p->rh_task = NULL;
374 p->pic = GNUNET_PEERSTORE_iterate (p->ph,
375 "transport",
376 &p->id,
377 GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY,
378 hello_iter_cb,
379 p);
380
381}
382
383
384struct GNUNET_TRANSPORT_TESTING_PeerContext *
385GNUNET_TRANSPORT_TESTING_start_peer (struct
386 GNUNET_TRANSPORT_TESTING_Handle *tth,
387 const char *cfgname,
388 int peer_id,
389 const struct
390 GNUNET_MQ_MessageHandler *handlers,
391 GNUNET_TRANSPORT_NotifyConnect nc,
392 GNUNET_TRANSPORT_NotifyDisconnect nd,
393 void *cb_cls,
394 GNUNET_SCHEDULER_TaskCallback start_cb,
395 void *start_cb_cls)
396{
397 char *emsg = NULL;
398 struct GNUNET_TRANSPORT_TESTING_PeerContext *p;
399 struct GNUNET_PeerIdentity dummy;
400 unsigned int i;
401
402 if (GNUNET_NO == GNUNET_DISK_file_test (cfgname))
403 {
404 LOG (GNUNET_ERROR_TYPE_ERROR,
405 "File not found: `%s'\n",
406 cfgname);
407 return NULL;
408 }
409
410 p = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_PeerContext);
411 p->tth = tth;
412 p->nc = nc;
413 p->nd = nd;
414 if (NULL != handlers)
415 {
416 for (i = 0; NULL != handlers[i].cb; i++)
417 ;
418 p->handlers = GNUNET_new_array (i + 1,
419 struct GNUNET_MQ_MessageHandler);
420 GNUNET_memcpy (p->handlers,
421 handlers,
422 i * sizeof(struct GNUNET_MQ_MessageHandler));
423 }
424 if (NULL != cb_cls)
425 p->cb_cls = cb_cls;
426 else
427 p->cb_cls = p;
428 p->start_cb = start_cb;
429 if (NULL != start_cb_cls)
430 p->start_cb_cls = start_cb_cls;
431 else
432 p->start_cb_cls = p;
433 GNUNET_CONTAINER_DLL_insert (tth->p_head,
434 tth->p_tail,
435 p);
436
437 /* Create configuration and call testing lib to modify it */
438 p->cfg = GNUNET_CONFIGURATION_create ();
439 GNUNET_assert (GNUNET_OK ==
440 GNUNET_CONFIGURATION_load (p->cfg, cfgname));
441 if (GNUNET_SYSERR ==
442 GNUNET_TESTING_configuration_create (tth->tl_system,
443 p->cfg))
444 {
445 LOG (GNUNET_ERROR_TYPE_ERROR,
446 "Testing library failed to create unique configuration based on `%s'\n",
447 cfgname);
448 GNUNET_CONFIGURATION_destroy (p->cfg);
449 GNUNET_free (p);
450 return NULL;
451 }
452
453 p->no = peer_id;
454 /* Configure peer with configuration */
455 p->peer = GNUNET_TESTING_peer_configure (tth->tl_system,
456 p->cfg,
457 p->no,
458 NULL,
459 &emsg);
460 if (NULL == p->peer)
461 {
462 LOG (GNUNET_ERROR_TYPE_ERROR,
463 "Testing library failed to create unique configuration based on `%s': `%s'\n",
464 cfgname,
465 emsg);
466 GNUNET_TRANSPORT_TESTING_stop_peer (p);
467 GNUNET_free (emsg);
468 return NULL;
469 }
470
471 if (GNUNET_OK != GNUNET_TESTING_peer_start (p->peer))
472 {
473 LOG (GNUNET_ERROR_TYPE_ERROR,
474 "Testing library failed to create unique configuration based on `%s'\n",
475 cfgname);
476 GNUNET_TRANSPORT_TESTING_stop_peer (p);
477 return NULL;
478 }
479
480 memset (&dummy,
481 '\0',
482 sizeof(dummy));
483 GNUNET_TESTING_peer_get_identity (p->peer,
484 &p->id);
485 if (0 == memcmp (&dummy,
486 &p->id,
487 sizeof(struct GNUNET_PeerIdentity)))
488 {
489 LOG (GNUNET_ERROR_TYPE_ERROR,
490 "Testing library failed to obtain peer identity for peer %u\n",
491 p->no);
492 GNUNET_TRANSPORT_TESTING_stop_peer (p);
493 return NULL;
494 }
495 LOG (GNUNET_ERROR_TYPE_DEBUG,
496 "Peer %u configured with identity `%s'\n",
497 p->no,
498 GNUNET_i2s_full (&p->id));
499 p->th = GNUNET_TRANSPORT_core_connect (p->cfg,
500 NULL,
501 handlers,
502 p,
503 &notify_connect,
504 &notify_disconnect);
505 if (NULL == p->th)
506 {
507 LOG (GNUNET_ERROR_TYPE_ERROR,
508 "Failed to connect to transport service for peer `%s': `%s'\n",
509 cfgname,
510 emsg);
511 GNUNET_TRANSPORT_TESTING_stop_peer (p);
512 GNUNET_free (emsg);
513 return NULL;
514 }
515 p->ats = GNUNET_ATS_connectivity_init (p->cfg);
516 if (NULL == p->ats)
517 {
518 LOG (GNUNET_ERROR_TYPE_ERROR,
519 "Failed to connect to ATS service for peer `%s': `%s'\n",
520 cfgname,
521 emsg);
522 GNUNET_TRANSPORT_TESTING_stop_peer (p);
523 GNUNET_free (emsg);
524 return NULL;
525 }
526 p->ph = GNUNET_PEERSTORE_connect (p->cfg);
527 // FIXME Error handling
528 p->ah = GNUNET_TRANSPORT_application_init (p->cfg);
529 GNUNET_assert (NULL != p->ah);
530 // FIXME Error handling
531 p->rh_task = GNUNET_SCHEDULER_add_now (retrieve_hello, p);
532
533 return p;
534}
535
536
537int
538GNUNET_TRANSPORT_TESTING_restart_peer (struct
539 GNUNET_TRANSPORT_TESTING_PeerContext *p,
540 GNUNET_SCHEDULER_TaskCallback restart_cb,
541 void *restart_cb_cls)
542{
543 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
544 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn;
545
546 /* shutdown */
547 LOG (GNUNET_ERROR_TYPE_DEBUG,
548 "Stopping peer %u (`%s')\n",
549 p->no,
550 GNUNET_i2s (&p->id));
551 if (NULL != p->pic)
552 {
553 GNUNET_PEERSTORE_iterate_cancel (p->pic);
554 p->pic = NULL;
555 }
556 if (NULL != p->th)
557 {
558 GNUNET_TRANSPORT_core_disconnect (p->th);
559 p->th = NULL;
560 }
561 for (cc = p->tth->cc_head; NULL != cc; cc = ccn)
562 {
563 ccn = cc->next;
564 if ((cc->p1 == p) ||
565 (cc->p2 == p))
566 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc);
567 }
568 if (NULL != p->ats)
569 {
570 GNUNET_ATS_connectivity_done (p->ats);
571 p->ats = NULL;
572 }
573 if (GNUNET_SYSERR ==
574 GNUNET_TESTING_peer_stop (p->peer))
575 {
576 LOG (GNUNET_ERROR_TYPE_ERROR,
577 "Failed to stop peer %u (`%s')\n",
578 p->no,
579 GNUNET_i2s (&p->id));
580 return GNUNET_SYSERR;
581 }
582
583 sleep (5); // YUCK!
584
585 LOG (GNUNET_ERROR_TYPE_DEBUG,
586 "Restarting peer %u (`%s')\n",
587 p->no,
588 GNUNET_i2s (&p->id));
589 /* restart */
590 if (GNUNET_SYSERR == GNUNET_TESTING_peer_start (p->peer))
591 {
592 LOG (GNUNET_ERROR_TYPE_ERROR,
593 "Failed to restart peer %u (`%s')\n",
594 p->no,
595 GNUNET_i2s (&p->id));
596 return GNUNET_SYSERR;
597 }
598
599 GNUNET_assert (NULL == p->start_cb);
600 p->start_cb = restart_cb;
601 p->start_cb_cls = restart_cb_cls;
602
603 p->th = GNUNET_TRANSPORT_core_connect (p->cfg,
604 NULL,
605 p->handlers,
606 p,
607 &notify_connect,
608 &notify_disconnect);
609 GNUNET_assert (NULL != p->th);
610 p->ats = GNUNET_ATS_connectivity_init (p->cfg);
611 p->pic = GNUNET_PEERSTORE_iterate (p->ph,
612 "transport",
613 &p->id,
614 GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY,
615 hello_iter_cb,
616 p);
617 GNUNET_assert (NULL != p->pic);
618 return GNUNET_OK;
619}
620
621
622/**
623 * Shutdown the given peer
624 *
625 * @param p the peer
626 */
627void
628GNUNET_TRANSPORT_TESTING_stop_peer (struct
629 GNUNET_TRANSPORT_TESTING_PeerContext *p)
630{
631 struct GNUNET_TRANSPORT_TESTING_Handle *tth = p->tth;
632 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
633 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn;
634 /* shutdown */
635 LOG (GNUNET_ERROR_TYPE_DEBUG,
636 "Stopping peer %u (`%s')\n",
637 p->no,
638 GNUNET_i2s (&p->id));
639
640 for (cc = tth->cc_head; NULL != cc; cc = ccn)
641 {
642 ccn = cc->next;
643 if ((cc->p1 == p) ||
644 (cc->p2 == p))
645 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc);
646 }
647 if (NULL != p->pic)
648 {
649 GNUNET_PEERSTORE_iterate_cancel (p->pic);
650 p->pic = NULL;
651 }
652 if (NULL != p->th)
653 {
654 GNUNET_TRANSPORT_core_disconnect (p->th);
655 p->th = NULL;
656 }
657 if (NULL != p->ats)
658 {
659 GNUNET_ATS_connectivity_done (p->ats);
660 p->ats = NULL;
661 }
662 if (NULL != p->ah)
663 {
664 GNUNET_TRANSPORT_application_done (p->ah);
665 p->ah = NULL;
666 }
667 if (NULL != p->ph)
668 {
669 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
670 "Disconnecting from PEERSTORE service\n");
671 GNUNET_PEERSTORE_disconnect (p->ph, GNUNET_NO);
672 p->ph = NULL;
673 }
674
675 if (NULL != p->peer)
676 {
677 if (GNUNET_OK !=
678 GNUNET_TESTING_peer_stop (p->peer))
679 {
680 LOG (GNUNET_ERROR_TYPE_DEBUG,
681 "Testing lib failed to stop peer %u (`%s')\n",
682 p->no,
683 GNUNET_i2s (&p->id));
684 }
685 GNUNET_TESTING_peer_destroy (p->peer);
686 p->peer = NULL;
687 }
688 if (NULL != p->hello)
689 {
690 GNUNET_free (p->hello);
691 p->hello = NULL;
692 }
693 if (NULL != p->cfg)
694 {
695 GNUNET_CONFIGURATION_destroy (p->cfg);
696 p->cfg = NULL;
697 }
698 if (NULL != p->handlers)
699 {
700 GNUNET_free (p->handlers);
701 p->handlers = NULL;
702 }
703 GNUNET_CONTAINER_DLL_remove (tth->p_head,
704 tth->p_tail,
705 p);
706 LOG (GNUNET_ERROR_TYPE_DEBUG,
707 "Peer %u (`%s') stopped\n",
708 p->no,
709 GNUNET_i2s (&p->id));
710 if (NULL != p->rh_task)
711 GNUNET_SCHEDULER_cancel (p->rh_task);
712 p->rh_task = NULL;
713 GNUNET_free (p);
714}
715
716
717/**
718 * Function called after the HELLO was passed to the
719 * transport service.
720 * FIXME maybe schedule the application_validate somehow
721 */
722/*
723 static void
724 hello_offered (void *cls)
725 {
726 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc = cls;
727
728 cc->oh = NULL;
729 cc->tct = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
730 &offer_hello,
731 cc);
732 }*/
733
734
735static void
736offer_hello (void *cls)
737{
738 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc = cls;
739 struct GNUNET_TRANSPORT_TESTING_PeerContext *p1 = cc->p1;
740 struct GNUNET_TRANSPORT_TESTING_PeerContext *p2 = cc->p2;
741 struct GNUNET_TIME_Absolute t;
742 enum GNUNET_NetworkType nt = 0;
743 char *addr;
744
745 cc->tct = NULL;
746 {
747 char *p2_s = GNUNET_strdup (GNUNET_i2s (&p2->id));
748
749 LOG (GNUNET_ERROR_TYPE_DEBUG,
750 "Asking peer %u (`%s') to connect peer %u (`%s'), providing HELLO with %s\n",
751 p1->no,
752 GNUNET_i2s (&p1->id),
753 p2->no,
754 p2_s,
755 p2->hello);
756 GNUNET_free (p2_s);
757 }
758
759 addr = GNUNET_HELLO_extract_address (p2->hello,
760 p2->hello_size,
761 &p2->id,
762 &nt,
763 &t);
764 GNUNET_assert (NULL != addr);
765 GNUNET_assert (NULL != p1->hello);
766 GNUNET_TRANSPORT_application_validate (p1->ah,
767 &p2->id,
768 nt,
769 addr);
770 GNUNET_free (addr);
771}
772
773
774/**
775 * Initiate a connection from p1 to p2 by offering p1 p2's HELLO message
776 *
777 * Remarks: start_peer's notify_connect callback can be called before.
778 *
779 * @param tth transport testing handle
780 * @param p1 peer 1
781 * @param p2 peer 2
782 * @param cb the callback to call when both peers notified that they are connected
783 * @param cls callback cls
784 * @return a connect request handle
785 */
786struct GNUNET_TRANSPORT_TESTING_ConnectRequest *
787GNUNET_TRANSPORT_TESTING_connect_peers (struct
788 GNUNET_TRANSPORT_TESTING_PeerContext *p1,
789 struct
790 GNUNET_TRANSPORT_TESTING_PeerContext *p2,
791 GNUNET_SCHEDULER_TaskCallback cb,
792 void *cls)
793{
794 struct GNUNET_TRANSPORT_TESTING_Handle *tth = p1->tth;
795 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
796 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn;
797
798 ccn = NULL;
799 for (cc = tth->cc_head; NULL != cc; cc = cc->next)
800 {
801 if ((cc->p1 == p1) &&
802 (cc->p2 == p2))
803 {
804 ccn = cc;
805 break;
806 }
807 }
808
809 cc = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_ConnectRequest);
810 cc->p1 = p1;
811 cc->p2 = p2;
812 cc->cb = cb;
813 if (NULL != cls)
814 cc->cb_cls = cls;
815 else
816 cc->cb_cls = cc;
817 if (NULL != ccn)
818 {
819 cc->p1_c = ccn->p1_c;
820 cc->p2_c = ccn->p2_c;
821 cc->connected = ccn->connected;
822 }
823 GNUNET_CONTAINER_DLL_insert (tth->cc_head,
824 tth->cc_tail,
825 cc);
826 cc->tct = GNUNET_SCHEDULER_add_now (&offer_hello,
827 cc);
828 cc->ats_sh = GNUNET_ATS_connectivity_suggest (cc->p1->ats,
829 &p2->id,
830 1);
831 LOG (GNUNET_ERROR_TYPE_DEBUG,
832 "New connect request %p\n",
833 cc);
834 return cc;
835}
836
837
838void
839GNUNET_TRANSPORT_TESTING_connect_peers_cancel (struct
840 GNUNET_TRANSPORT_TESTING_ConnectRequest
841 *cc)
842{
843 struct GNUNET_TRANSPORT_TESTING_Handle *tth = cc->p1->tth;
844
845 LOG (GNUNET_ERROR_TYPE_DEBUG,
846 "Canceling connect request!\n");
847 if (NULL != cc->tct)
848 {
849 GNUNET_SCHEDULER_cancel (cc->tct);
850 cc->tct = NULL;
851 }
852 if (NULL != cc->ats_sh)
853 {
854 GNUNET_ATS_connectivity_suggest_cancel (cc->ats_sh);
855 cc->ats_sh = NULL;
856 }
857 GNUNET_CONTAINER_DLL_remove (tth->cc_head,
858 tth->cc_tail,
859 cc);
860 GNUNET_free (cc);
861}
862
863
864/**
865 * Clean up the transport testing
866 *
867 * @param tth transport testing handle
868 */
869void
870GNUNET_TRANSPORT_TESTING_done (struct GNUNET_TRANSPORT_TESTING_Handle *tth)
871{
872 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
873 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ct;
874 struct GNUNET_TRANSPORT_TESTING_PeerContext *p;
875 struct GNUNET_TRANSPORT_TESTING_PeerContext *t;
876
877 if (NULL == tth)
878 return;
879 cc = tth->cc_head;
880 while (NULL != cc)
881 {
882 ct = cc->next;
883 LOG (GNUNET_ERROR_TYPE_ERROR,
884 "Developer forgot to cancel connect request!\n");
885 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc);
886 cc = ct;
887 }
888 p = tth->p_head;
889 while (NULL != p)
890 {
891 t = p->next;
892 LOG (GNUNET_ERROR_TYPE_ERROR,
893 "Developer forgot to stop peer!\n");
894 GNUNET_TRANSPORT_TESTING_stop_peer (p);
895 p = t;
896 }
897 GNUNET_TESTING_system_destroy (tth->tl_system,
898 GNUNET_YES);
899
900 GNUNET_free (tth);
901}
902
903
904/**
905 * Initialize the transport testing
906 *
907 * @return transport testing handle
908 */
909struct GNUNET_TRANSPORT_TESTING_Handle *
910GNUNET_TRANSPORT_TESTING_init ()
911{
912 struct GNUNET_TRANSPORT_TESTING_Handle *tth;
913
914 tth = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_Handle);
915 tth->tl_system = GNUNET_TESTING_system_create ("transport-testing",
916 NULL,
917 NULL,
918 NULL);
919 if (NULL == tth->tl_system)
920 {
921 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
922 "Failed to initialize testing library!\n");
923 GNUNET_free (tth);
924 return NULL;
925 }
926 return tth;
927}
928
929
930/* end of transport-testing.c */