aboutsummaryrefslogtreecommitdiff
path: root/src/service/transport/transport-testing2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/transport/transport-testing2.c')
-rw-r--r--src/service/transport/transport-testing2.c871
1 files changed, 871 insertions, 0 deletions
diff --git a/src/service/transport/transport-testing2.c b/src/service/transport/transport-testing2.c
new file mode 100644
index 000000000..877730630
--- /dev/null
+++ b/src/service/transport/transport-testing2.c
@@ -0,0 +1,871 @@
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->ah_sh)
229 {
230 GNUNET_TRANSPORT_application_suggest_cancel (cc->ah_sh);
231 cc->ah_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
250static void
251notify_disconnect (void *cls,
252 const struct GNUNET_PeerIdentity *peer,
253 void *handler_cls)
254{
255 struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
256 struct GNUNET_TRANSPORT_TESTING_Handle *tth = p->tth;
257 char *p2_s;
258 /* Find PeerContext */
259 int no = 0;
260 struct GNUNET_TRANSPORT_TESTING_PeerContext *p2 = NULL;
261 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
262
263 p2 = find_peer_context (p->tth,
264 peer);
265 no = p->no;
266 if (NULL != p2)
267 GNUNET_asprintf (&p2_s,
268 "%u (`%s')",
269 p2->no,
270 GNUNET_i2s (&p2->id));
271 else
272 GNUNET_asprintf (&p2_s,
273 "`%s'",
274 GNUNET_i2s (peer));
275 LOG (GNUNET_ERROR_TYPE_DEBUG,
276 "Peers %s disconnected from peer %u (`%s')\n",
277 p2_s,
278 no,
279 GNUNET_i2s (&p->id));
280 GNUNET_free (p2_s);
281 /* notify about disconnect */
282 if (NULL != p->nd)
283 p->nd (p->cb_cls,
284 peer,
285 handler_cls);
286 if (NULL == p2)
287 return;
288 /* clear MQ, it is now invalid */
289 GNUNET_TRANSPORT_TESTING_find_connecting_context (p,
290 p2,
291 &set_mq,
292 NULL);
293 /* update set connected flags for all requests */
294 GNUNET_TRANSPORT_TESTING_find_connecting_context (p,
295 p2,
296 &clear_p1c,
297 NULL);
298 GNUNET_TRANSPORT_TESTING_find_connecting_context (p2,
299 p,
300 &clear_p2c,
301 NULL);
302 /* resume connectivity requests as necessary */
303 for (cc = tth->cc_head; NULL != cc; cc = cc->next)
304 {
305 if (GNUNET_NO == cc->connected)
306 continue;
307 if ((GNUNET_YES != cc->p1_c) ||
308 (GNUNET_YES != cc->p2_c))
309 {
310 cc->connected = GNUNET_NO;
311 /* start trying to connect */
312 if (NULL == cc->ah_sh)
313 cc->ah_sh = GNUNET_TRANSPORT_application_suggest (cc->p1->ah,
314 &p2->id,
315 GNUNET_MQ_PRIO_BEST_EFFORT,
316 GNUNET_BANDWIDTH_ZERO);
317 }
318 }
319}
320
321
322static void
323retrieve_hello (void *cls);
324
325static void
326hello_iter_cb (void *cb_cls,
327 const struct GNUNET_PEERSTORE_Record *record,
328 const char *emsg)
329{
330 struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cb_cls;
331 if (NULL == record)
332 {
333 p->pic = NULL;
334 if (NULL != p->start_cb)
335 p->rh_task = GNUNET_SCHEDULER_add_now (retrieve_hello, p);
336 return;
337 }
338 // Check record type et al?
339 p->hello_size = record->value_size;
340 p->hello = GNUNET_malloc (p->hello_size);
341 memcpy (p->hello, record->value, p->hello_size);
342 p->hello[p->hello_size - 1] = '\0';
343
344 GNUNET_PEERSTORE_iteration_stop (p->pic);
345 p->pic = NULL;
346 if (NULL != p->start_cb)
347 {
348 LOG (GNUNET_ERROR_TYPE_DEBUG,
349 "Peer %u (`%s') successfully started\n",
350 p->no,
351 GNUNET_i2s (&p->id));
352 p->start_cb (p->start_cb_cls);
353 p->start_cb = NULL;
354 }
355}
356
357
358static void
359retrieve_hello (void *cls)
360{
361 struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
362 p->rh_task = NULL;
363 p->pic = GNUNET_PEERSTORE_iteration_start (p->ph,
364 "transport",
365 &p->id,
366 GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY,
367 hello_iter_cb,
368 p);
369
370}
371
372
373struct GNUNET_TRANSPORT_TESTING_PeerContext *
374GNUNET_TRANSPORT_TESTING_start_peer (struct
375 GNUNET_TRANSPORT_TESTING_Handle *tth,
376 const char *cfgname,
377 int peer_id,
378 const struct
379 GNUNET_MQ_MessageHandler *handlers,
380 GNUNET_TRANSPORT_NotifyConnect nc,
381 GNUNET_TRANSPORT_NotifyDisconnect nd,
382 void *cb_cls,
383 GNUNET_SCHEDULER_TaskCallback start_cb,
384 void *start_cb_cls)
385{
386 char *emsg = NULL;
387 struct GNUNET_TRANSPORT_TESTING_PeerContext *p;
388 struct GNUNET_PeerIdentity dummy;
389 unsigned int i;
390
391 if (GNUNET_NO == GNUNET_DISK_file_test (cfgname))
392 {
393 LOG (GNUNET_ERROR_TYPE_ERROR,
394 "File not found: `%s'\n",
395 cfgname);
396 return NULL;
397 }
398
399 p = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_PeerContext);
400 p->tth = tth;
401 p->nc = nc;
402 p->nd = nd;
403 if (NULL != handlers)
404 {
405 for (i = 0; NULL != handlers[i].cb; i++)
406 ;
407 p->handlers = GNUNET_new_array (i + 1,
408 struct GNUNET_MQ_MessageHandler);
409 GNUNET_memcpy (p->handlers,
410 handlers,
411 i * sizeof(struct GNUNET_MQ_MessageHandler));
412 }
413 if (NULL != cb_cls)
414 p->cb_cls = cb_cls;
415 else
416 p->cb_cls = p;
417 p->start_cb = start_cb;
418 if (NULL != start_cb_cls)
419 p->start_cb_cls = start_cb_cls;
420 else
421 p->start_cb_cls = p;
422 GNUNET_CONTAINER_DLL_insert (tth->p_head,
423 tth->p_tail,
424 p);
425
426 /* Create configuration and call testing lib to modify it */
427 p->cfg = GNUNET_CONFIGURATION_create ();
428 GNUNET_assert (GNUNET_OK ==
429 GNUNET_CONFIGURATION_load (p->cfg, cfgname));
430 if (GNUNET_SYSERR ==
431 GNUNET_TESTING_configuration_create (tth->tl_system,
432 p->cfg))
433 {
434 LOG (GNUNET_ERROR_TYPE_ERROR,
435 "Testing library failed to create unique configuration based on `%s'\n",
436 cfgname);
437 GNUNET_CONFIGURATION_destroy (p->cfg);
438 GNUNET_free (p);
439 return NULL;
440 }
441
442 p->no = peer_id;
443 /* Configure peer with configuration */
444 p->peer = GNUNET_TESTING_peer_configure (tth->tl_system,
445 p->cfg,
446 p->no,
447 NULL,
448 &emsg);
449 if (NULL == p->peer)
450 {
451 LOG (GNUNET_ERROR_TYPE_ERROR,
452 "Testing library failed to create unique configuration based on `%s': `%s'\n",
453 cfgname,
454 emsg);
455 GNUNET_TRANSPORT_TESTING_stop_peer (p);
456 GNUNET_free (emsg);
457 return NULL;
458 }
459
460 if (GNUNET_OK != GNUNET_TESTING_peer_start (p->peer))
461 {
462 LOG (GNUNET_ERROR_TYPE_ERROR,
463 "Testing library failed to create unique configuration based on `%s'\n",
464 cfgname);
465 GNUNET_TRANSPORT_TESTING_stop_peer (p);
466 return NULL;
467 }
468
469 memset (&dummy,
470 '\0',
471 sizeof(dummy));
472 GNUNET_TESTING_peer_get_identity (p->peer,
473 &p->id);
474 if (0 == memcmp (&dummy,
475 &p->id,
476 sizeof(struct GNUNET_PeerIdentity)))
477 {
478 LOG (GNUNET_ERROR_TYPE_ERROR,
479 "Testing library failed to obtain peer identity for peer %u\n",
480 p->no);
481 GNUNET_TRANSPORT_TESTING_stop_peer (p);
482 return NULL;
483 }
484 LOG (GNUNET_ERROR_TYPE_DEBUG,
485 "Peer %u configured with identity `%s'\n",
486 p->no,
487 GNUNET_i2s_full (&p->id));
488 p->th = GNUNET_TRANSPORT_core_connect (p->cfg,
489 NULL,
490 handlers,
491 p,
492 &notify_connect,
493 &notify_disconnect);
494 if (NULL == p->th)
495 {
496 LOG (GNUNET_ERROR_TYPE_ERROR,
497 "Failed to connect to transport service for peer `%s': `%s'\n",
498 cfgname,
499 emsg);
500 GNUNET_TRANSPORT_TESTING_stop_peer (p);
501 GNUNET_free (emsg);
502 return NULL;
503 }
504 p->ah = GNUNET_TRANSPORT_application_init (p->cfg);
505 if (NULL == p->ah)
506 {
507 LOG (GNUNET_ERROR_TYPE_ERROR,
508 "Failed to connect to TNG 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->ph = GNUNET_PEERSTORE_connect (p->cfg);
516 // FIXME Error handling
517 p->rh_task = GNUNET_SCHEDULER_add_now (retrieve_hello, p);
518
519 return p;
520}
521
522
523int
524GNUNET_TRANSPORT_TESTING_restart_peer (struct
525 GNUNET_TRANSPORT_TESTING_PeerContext *p,
526 GNUNET_SCHEDULER_TaskCallback restart_cb,
527 void *restart_cb_cls)
528{
529 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
530 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn;
531
532 /* shutdown */
533 LOG (GNUNET_ERROR_TYPE_DEBUG,
534 "Stopping peer %u (`%s')\n",
535 p->no,
536 GNUNET_i2s (&p->id));
537 if (NULL != p->pic)
538 {
539 GNUNET_PEERSTORE_iteration_stop (p->pic);
540 p->pic = NULL;
541 }
542 if (NULL != p->th)
543 {
544 GNUNET_TRANSPORT_core_disconnect (p->th);
545 p->th = NULL;
546 }
547 for (cc = p->tth->cc_head; NULL != cc; cc = ccn)
548 {
549 ccn = cc->next;
550 if ((cc->p1 == p) ||
551 (cc->p2 == p))
552 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc);
553 }
554 if (NULL != p->ah)
555 {
556 GNUNET_TRANSPORT_application_done (p->ah);
557 p->ah = NULL;
558 }
559 if (GNUNET_SYSERR ==
560 GNUNET_TESTING_peer_stop (p->peer))
561 {
562 LOG (GNUNET_ERROR_TYPE_ERROR,
563 "Failed to stop peer %u (`%s')\n",
564 p->no,
565 GNUNET_i2s (&p->id));
566 return GNUNET_SYSERR;
567 }
568
569 sleep (5); // YUCK!
570
571 LOG (GNUNET_ERROR_TYPE_DEBUG,
572 "Restarting peer %u (`%s')\n",
573 p->no,
574 GNUNET_i2s (&p->id));
575 /* restart */
576 if (GNUNET_SYSERR == GNUNET_TESTING_peer_start (p->peer))
577 {
578 LOG (GNUNET_ERROR_TYPE_ERROR,
579 "Failed to restart peer %u (`%s')\n",
580 p->no,
581 GNUNET_i2s (&p->id));
582 return GNUNET_SYSERR;
583 }
584
585 GNUNET_assert (NULL == p->start_cb);
586 p->start_cb = restart_cb;
587 p->start_cb_cls = restart_cb_cls;
588
589 p->th = GNUNET_TRANSPORT_core_connect (p->cfg,
590 NULL,
591 p->handlers,
592 p,
593 &notify_connect,
594 &notify_disconnect);
595 GNUNET_assert (NULL != p->th);
596 p->ah = GNUNET_TRANSPORT_application_init (p->cfg);
597 p->pic = GNUNET_PEERSTORE_iteration_start (p->ph,
598 "transport",
599 &p->id,
600 GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY,
601 hello_iter_cb,
602 p);
603 GNUNET_assert (NULL != p->pic);
604 return GNUNET_OK;
605}
606
607
608/**
609 * Shutdown the given peer
610 *
611 * @param p the peer
612 */
613void
614GNUNET_TRANSPORT_TESTING_stop_peer (struct
615 GNUNET_TRANSPORT_TESTING_PeerContext *p)
616{
617 struct GNUNET_TRANSPORT_TESTING_Handle *tth = p->tth;
618 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
619 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn;
620 /* shutdown */
621 LOG (GNUNET_ERROR_TYPE_DEBUG,
622 "Stopping peer %u (`%s')\n",
623 p->no,
624 GNUNET_i2s (&p->id));
625
626 for (cc = tth->cc_head; NULL != cc; cc = ccn)
627 {
628 ccn = cc->next;
629 if ((cc->p1 == p) ||
630 (cc->p2 == p))
631 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc);
632 }
633 if (NULL != p->pic)
634 {
635 GNUNET_PEERSTORE_iteration_stop (p->pic);
636 p->pic = NULL;
637 }
638 if (NULL != p->th)
639 {
640 GNUNET_TRANSPORT_core_disconnect (p->th);
641 p->th = NULL;
642 }
643 if (NULL != p->ah)
644 {
645 GNUNET_TRANSPORT_application_done (p->ah);
646 p->ah = NULL;
647 }
648 if (NULL != p->ph)
649 {
650 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
651 "Disconnecting from PEERSTORE service\n");
652 GNUNET_PEERSTORE_disconnect (p->ph);
653 p->ph = NULL;
654 }
655
656 if (NULL != p->peer)
657 {
658 if (GNUNET_OK !=
659 GNUNET_TESTING_peer_stop (p->peer))
660 {
661 LOG (GNUNET_ERROR_TYPE_DEBUG,
662 "Testing lib failed to stop peer %u (`%s')\n",
663 p->no,
664 GNUNET_i2s (&p->id));
665 }
666 GNUNET_TESTING_peer_destroy (p->peer);
667 p->peer = NULL;
668 }
669 if (NULL != p->hello)
670 {
671 GNUNET_free (p->hello);
672 p->hello = NULL;
673 }
674 if (NULL != p->cfg)
675 {
676 GNUNET_CONFIGURATION_destroy (p->cfg);
677 p->cfg = NULL;
678 }
679 if (NULL != p->handlers)
680 {
681 GNUNET_free (p->handlers);
682 p->handlers = NULL;
683 }
684 GNUNET_CONTAINER_DLL_remove (tth->p_head,
685 tth->p_tail,
686 p);
687 LOG (GNUNET_ERROR_TYPE_DEBUG,
688 "Peer %u (`%s') stopped\n",
689 p->no,
690 GNUNET_i2s (&p->id));
691 if (NULL != p->rh_task)
692 GNUNET_SCHEDULER_cancel (p->rh_task);
693 p->rh_task = NULL;
694 GNUNET_free (p);
695}
696
697
698/**
699 * Function called after the HELLO was passed to the
700 * transport service.
701 * FIXME maybe schedule the application_validate somehow
702 */
703/*
704 static void
705 hello_offered (void *cls)
706 {
707 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc = cls;
708
709 cc->oh = NULL;
710 cc->tct = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
711 &offer_hello,
712 cc);
713 }*/
714
715
716/**
717 * Initiate a connection from p1 to p2 by offering p1 p2's HELLO message
718 *
719 * Remarks: start_peer's notify_connect callback can be called before.
720 *
721 * @param tth transport testing handle
722 * @param p1 peer 1
723 * @param p2 peer 2
724 * @param cb the callback to call when both peers notified that they are connected
725 * @param cls callback cls
726 * @return a connect request handle
727 */
728struct GNUNET_TRANSPORT_TESTING_ConnectRequest *
729GNUNET_TRANSPORT_TESTING_connect_peers (struct
730 GNUNET_TRANSPORT_TESTING_PeerContext *p1,
731 struct
732 GNUNET_TRANSPORT_TESTING_PeerContext *p2,
733 GNUNET_SCHEDULER_TaskCallback cb,
734 void *cls)
735{
736 struct GNUNET_TRANSPORT_TESTING_Handle *tth = p1->tth;
737 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
738 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn;
739
740 ccn = NULL;
741 for (cc = tth->cc_head; NULL != cc; cc = cc->next)
742 {
743 if ((cc->p1 == p1) &&
744 (cc->p2 == p2))
745 {
746 ccn = cc;
747 break;
748 }
749 }
750
751 cc = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_ConnectRequest);
752 cc->p1 = p1;
753 cc->p2 = p2;
754 cc->cb = cb;
755 if (NULL != cls)
756 cc->cb_cls = cls;
757 else
758 cc->cb_cls = cc;
759 if (NULL != ccn)
760 {
761 cc->p1_c = ccn->p1_c;
762 cc->p2_c = ccn->p2_c;
763 cc->connected = ccn->connected;
764 }
765 GNUNET_CONTAINER_DLL_insert (tth->cc_head,
766 tth->cc_tail,
767 cc);
768 cc->ah_sh = GNUNET_TRANSPORT_application_suggest (cc->p1->ah,
769 &p2->id,
770 GNUNET_MQ_PRIO_BEST_EFFORT,
771 GNUNET_BANDWIDTH_ZERO);
772 LOG (GNUNET_ERROR_TYPE_DEBUG,
773 "New connect request %p\n",
774 cc);
775 return cc;
776}
777
778
779void
780GNUNET_TRANSPORT_TESTING_connect_peers_cancel (struct
781 GNUNET_TRANSPORT_TESTING_ConnectRequest
782 *cc)
783{
784 struct GNUNET_TRANSPORT_TESTING_Handle *tth = cc->p1->tth;
785
786 LOG (GNUNET_ERROR_TYPE_DEBUG,
787 "Canceling connect request!\n");
788 if (NULL != cc->tct)
789 {
790 GNUNET_SCHEDULER_cancel (cc->tct);
791 cc->tct = NULL;
792 }
793 if (NULL != cc->ah_sh)
794 {
795 GNUNET_TRANSPORT_application_suggest_cancel (cc->ah_sh);
796 cc->ah_sh = NULL;
797 }
798 GNUNET_CONTAINER_DLL_remove (tth->cc_head,
799 tth->cc_tail,
800 cc);
801 GNUNET_free (cc);
802}
803
804
805/**
806 * Clean up the transport testing
807 *
808 * @param tth transport testing handle
809 */
810void
811GNUNET_TRANSPORT_TESTING_done (struct GNUNET_TRANSPORT_TESTING_Handle *tth)
812{
813 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
814 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ct;
815 struct GNUNET_TRANSPORT_TESTING_PeerContext *p;
816 struct GNUNET_TRANSPORT_TESTING_PeerContext *t;
817
818 if (NULL == tth)
819 return;
820 cc = tth->cc_head;
821 while (NULL != cc)
822 {
823 ct = cc->next;
824 LOG (GNUNET_ERROR_TYPE_ERROR,
825 "Developer forgot to cancel connect request!\n");
826 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc);
827 cc = ct;
828 }
829 p = tth->p_head;
830 while (NULL != p)
831 {
832 t = p->next;
833 LOG (GNUNET_ERROR_TYPE_ERROR,
834 "Developer forgot to stop peer!\n");
835 GNUNET_TRANSPORT_TESTING_stop_peer (p);
836 p = t;
837 }
838 GNUNET_TESTING_system_destroy (tth->tl_system,
839 GNUNET_YES);
840
841 GNUNET_free (tth);
842}
843
844
845/**
846 * Initialize the transport testing
847 *
848 * @return transport testing handle
849 */
850struct GNUNET_TRANSPORT_TESTING_Handle *
851GNUNET_TRANSPORT_TESTING_init ()
852{
853 struct GNUNET_TRANSPORT_TESTING_Handle *tth;
854
855 tth = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_Handle);
856 tth->tl_system = GNUNET_TESTING_system_create ("transport-testing",
857 NULL,
858 NULL,
859 NULL);
860 if (NULL == tth->tl_system)
861 {
862 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
863 "Failed to initialize testing library!\n");
864 GNUNET_free (tth);
865 return NULL;
866 }
867 return tth;
868}
869
870
871/* end of transport-testing.c */