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.c929
1 files changed, 0 insertions, 929 deletions
diff --git a/src/transport/transport-testing2.c b/src/transport/transport-testing2.c
deleted file mode 100644
index 566e0db71..000000000
--- a/src/transport/transport-testing2.c
+++ /dev/null
@@ -1,929 +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
332static void
333retrieve_hello (void *cls);
334
335static void
336hello_iter_cb (void *cb_cls,
337 const struct GNUNET_PEERSTORE_Record *record,
338 const char *emsg)
339{
340 struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cb_cls;
341 if (NULL == record)
342 {
343 p->pic = NULL;
344 if (NULL != p->start_cb)
345 p->rh_task = GNUNET_SCHEDULER_add_now (retrieve_hello, p);
346 return;
347 }
348 // Check record type et al?
349 p->hello_size = record->value_size;
350 p->hello = GNUNET_malloc (p->hello_size);
351 memcpy (p->hello, record->value, p->hello_size);
352 p->hello[p->hello_size - 1] = '\0';
353
354 GNUNET_PEERSTORE_iterate_cancel (p->pic);
355 p->pic = NULL;
356 if (NULL != p->start_cb)
357 {
358 LOG (GNUNET_ERROR_TYPE_DEBUG,
359 "Peer %u (`%s') successfully started\n",
360 p->no,
361 GNUNET_i2s (&p->id));
362 p->start_cb (p->start_cb_cls);
363 p->start_cb = NULL;
364 }
365}
366
367
368static void
369retrieve_hello (void *cls)
370{
371 struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
372 p->rh_task = NULL;
373 p->pic = GNUNET_PEERSTORE_iterate (p->ph,
374 "transport",
375 &p->id,
376 GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY,
377 hello_iter_cb,
378 p);
379
380}
381
382
383struct GNUNET_TRANSPORT_TESTING_PeerContext *
384GNUNET_TRANSPORT_TESTING_start_peer (struct
385 GNUNET_TRANSPORT_TESTING_Handle *tth,
386 const char *cfgname,
387 int peer_id,
388 const struct
389 GNUNET_MQ_MessageHandler *handlers,
390 GNUNET_TRANSPORT_NotifyConnect nc,
391 GNUNET_TRANSPORT_NotifyDisconnect nd,
392 void *cb_cls,
393 GNUNET_SCHEDULER_TaskCallback start_cb,
394 void *start_cb_cls)
395{
396 char *emsg = NULL;
397 struct GNUNET_TRANSPORT_TESTING_PeerContext *p;
398 struct GNUNET_PeerIdentity dummy;
399 unsigned int i;
400
401 if (GNUNET_NO == GNUNET_DISK_file_test (cfgname))
402 {
403 LOG (GNUNET_ERROR_TYPE_ERROR,
404 "File not found: `%s'\n",
405 cfgname);
406 return NULL;
407 }
408
409 p = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_PeerContext);
410 p->tth = tth;
411 p->nc = nc;
412 p->nd = nd;
413 if (NULL != handlers)
414 {
415 for (i = 0; NULL != handlers[i].cb; i++)
416 ;
417 p->handlers = GNUNET_new_array (i + 1,
418 struct GNUNET_MQ_MessageHandler);
419 GNUNET_memcpy (p->handlers,
420 handlers,
421 i * sizeof(struct GNUNET_MQ_MessageHandler));
422 }
423 if (NULL != cb_cls)
424 p->cb_cls = cb_cls;
425 else
426 p->cb_cls = p;
427 p->start_cb = start_cb;
428 if (NULL != start_cb_cls)
429 p->start_cb_cls = start_cb_cls;
430 else
431 p->start_cb_cls = p;
432 GNUNET_CONTAINER_DLL_insert (tth->p_head,
433 tth->p_tail,
434 p);
435
436 /* Create configuration and call testing lib to modify it */
437 p->cfg = GNUNET_CONFIGURATION_create ();
438 GNUNET_assert (GNUNET_OK ==
439 GNUNET_CONFIGURATION_load (p->cfg, cfgname));
440 if (GNUNET_SYSERR ==
441 GNUNET_TESTING_configuration_create (tth->tl_system,
442 p->cfg))
443 {
444 LOG (GNUNET_ERROR_TYPE_ERROR,
445 "Testing library failed to create unique configuration based on `%s'\n",
446 cfgname);
447 GNUNET_CONFIGURATION_destroy (p->cfg);
448 GNUNET_free (p);
449 return NULL;
450 }
451
452 p->no = peer_id;
453 /* Configure peer with configuration */
454 p->peer = GNUNET_TESTING_peer_configure (tth->tl_system,
455 p->cfg,
456 p->no,
457 NULL,
458 &emsg);
459 if (NULL == p->peer)
460 {
461 LOG (GNUNET_ERROR_TYPE_ERROR,
462 "Testing library failed to create unique configuration based on `%s': `%s'\n",
463 cfgname,
464 emsg);
465 GNUNET_TRANSPORT_TESTING_stop_peer (p);
466 GNUNET_free (emsg);
467 return NULL;
468 }
469
470 if (GNUNET_OK != GNUNET_TESTING_peer_start (p->peer))
471 {
472 LOG (GNUNET_ERROR_TYPE_ERROR,
473 "Testing library failed to create unique configuration based on `%s'\n",
474 cfgname);
475 GNUNET_TRANSPORT_TESTING_stop_peer (p);
476 return NULL;
477 }
478
479 memset (&dummy,
480 '\0',
481 sizeof(dummy));
482 GNUNET_TESTING_peer_get_identity (p->peer,
483 &p->id);
484 if (0 == memcmp (&dummy,
485 &p->id,
486 sizeof(struct GNUNET_PeerIdentity)))
487 {
488 LOG (GNUNET_ERROR_TYPE_ERROR,
489 "Testing library failed to obtain peer identity for peer %u\n",
490 p->no);
491 GNUNET_TRANSPORT_TESTING_stop_peer (p);
492 return NULL;
493 }
494 LOG (GNUNET_ERROR_TYPE_DEBUG,
495 "Peer %u configured with identity `%s'\n",
496 p->no,
497 GNUNET_i2s_full (&p->id));
498 p->th = GNUNET_TRANSPORT_core_connect (p->cfg,
499 NULL,
500 handlers,
501 p,
502 &notify_connect,
503 &notify_disconnect);
504 if (NULL == p->th)
505 {
506 LOG (GNUNET_ERROR_TYPE_ERROR,
507 "Failed to connect to transport service for peer `%s': `%s'\n",
508 cfgname,
509 emsg);
510 GNUNET_TRANSPORT_TESTING_stop_peer (p);
511 GNUNET_free (emsg);
512 return NULL;
513 }
514 p->ats = GNUNET_ATS_connectivity_init (p->cfg);
515 if (NULL == p->ats)
516 {
517 LOG (GNUNET_ERROR_TYPE_ERROR,
518 "Failed to connect to ATS service for peer `%s': `%s'\n",
519 cfgname,
520 emsg);
521 GNUNET_TRANSPORT_TESTING_stop_peer (p);
522 GNUNET_free (emsg);
523 return NULL;
524 }
525 p->ph = GNUNET_PEERSTORE_connect (p->cfg);
526 // FIXME Error handling
527 p->ah = GNUNET_TRANSPORT_application_init (p->cfg);
528 GNUNET_assert (NULL != p->ah);
529 // FIXME Error handling
530 p->rh_task = GNUNET_SCHEDULER_add_now (retrieve_hello, p);
531
532 return p;
533}
534
535
536int
537GNUNET_TRANSPORT_TESTING_restart_peer (struct
538 GNUNET_TRANSPORT_TESTING_PeerContext *p,
539 GNUNET_SCHEDULER_TaskCallback restart_cb,
540 void *restart_cb_cls)
541{
542 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
543 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn;
544
545 /* shutdown */
546 LOG (GNUNET_ERROR_TYPE_DEBUG,
547 "Stopping peer %u (`%s')\n",
548 p->no,
549 GNUNET_i2s (&p->id));
550 if (NULL != p->pic)
551 {
552 GNUNET_PEERSTORE_iterate_cancel (p->pic);
553 p->pic = NULL;
554 }
555 if (NULL != p->th)
556 {
557 GNUNET_TRANSPORT_core_disconnect (p->th);
558 p->th = NULL;
559 }
560 for (cc = p->tth->cc_head; NULL != cc; cc = ccn)
561 {
562 ccn = cc->next;
563 if ((cc->p1 == p) ||
564 (cc->p2 == p))
565 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc);
566 }
567 if (NULL != p->ats)
568 {
569 GNUNET_ATS_connectivity_done (p->ats);
570 p->ats = NULL;
571 }
572 if (GNUNET_SYSERR ==
573 GNUNET_TESTING_peer_stop (p->peer))
574 {
575 LOG (GNUNET_ERROR_TYPE_ERROR,
576 "Failed to stop peer %u (`%s')\n",
577 p->no,
578 GNUNET_i2s (&p->id));
579 return GNUNET_SYSERR;
580 }
581
582 sleep (5); // YUCK!
583
584 LOG (GNUNET_ERROR_TYPE_DEBUG,
585 "Restarting peer %u (`%s')\n",
586 p->no,
587 GNUNET_i2s (&p->id));
588 /* restart */
589 if (GNUNET_SYSERR == GNUNET_TESTING_peer_start (p->peer))
590 {
591 LOG (GNUNET_ERROR_TYPE_ERROR,
592 "Failed to restart peer %u (`%s')\n",
593 p->no,
594 GNUNET_i2s (&p->id));
595 return GNUNET_SYSERR;
596 }
597
598 GNUNET_assert (NULL == p->start_cb);
599 p->start_cb = restart_cb;
600 p->start_cb_cls = restart_cb_cls;
601
602 p->th = GNUNET_TRANSPORT_core_connect (p->cfg,
603 NULL,
604 p->handlers,
605 p,
606 &notify_connect,
607 &notify_disconnect);
608 GNUNET_assert (NULL != p->th);
609 p->ats = GNUNET_ATS_connectivity_init (p->cfg);
610 p->pic = GNUNET_PEERSTORE_iterate (p->ph,
611 "transport",
612 &p->id,
613 GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY,
614 hello_iter_cb,
615 p);
616 GNUNET_assert (NULL != p->pic);
617 return GNUNET_OK;
618}
619
620
621/**
622 * Shutdown the given peer
623 *
624 * @param p the peer
625 */
626void
627GNUNET_TRANSPORT_TESTING_stop_peer (struct
628 GNUNET_TRANSPORT_TESTING_PeerContext *p)
629{
630 struct GNUNET_TRANSPORT_TESTING_Handle *tth = p->tth;
631 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
632 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn;
633 /* shutdown */
634 LOG (GNUNET_ERROR_TYPE_DEBUG,
635 "Stopping peer %u (`%s')\n",
636 p->no,
637 GNUNET_i2s (&p->id));
638
639 for (cc = tth->cc_head; NULL != cc; cc = ccn)
640 {
641 ccn = cc->next;
642 if ((cc->p1 == p) ||
643 (cc->p2 == p))
644 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc);
645 }
646 if (NULL != p->pic)
647 {
648 GNUNET_PEERSTORE_iterate_cancel (p->pic);
649 p->pic = NULL;
650 }
651 if (NULL != p->th)
652 {
653 GNUNET_TRANSPORT_core_disconnect (p->th);
654 p->th = NULL;
655 }
656 if (NULL != p->ats)
657 {
658 GNUNET_ATS_connectivity_done (p->ats);
659 p->ats = NULL;
660 }
661 if (NULL != p->ah)
662 {
663 GNUNET_TRANSPORT_application_done (p->ah);
664 p->ah = NULL;
665 }
666 if (NULL != p->ph)
667 {
668 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
669 "Disconnecting from PEERSTORE service\n");
670 GNUNET_PEERSTORE_disconnect (p->ph, GNUNET_NO);
671 p->ph = NULL;
672 }
673
674 if (NULL != p->peer)
675 {
676 if (GNUNET_OK !=
677 GNUNET_TESTING_peer_stop (p->peer))
678 {
679 LOG (GNUNET_ERROR_TYPE_DEBUG,
680 "Testing lib failed to stop peer %u (`%s')\n",
681 p->no,
682 GNUNET_i2s (&p->id));
683 }
684 GNUNET_TESTING_peer_destroy (p->peer);
685 p->peer = NULL;
686 }
687 if (NULL != p->hello)
688 {
689 GNUNET_free (p->hello);
690 p->hello = NULL;
691 }
692 if (NULL != p->cfg)
693 {
694 GNUNET_CONFIGURATION_destroy (p->cfg);
695 p->cfg = NULL;
696 }
697 if (NULL != p->handlers)
698 {
699 GNUNET_free (p->handlers);
700 p->handlers = NULL;
701 }
702 GNUNET_CONTAINER_DLL_remove (tth->p_head,
703 tth->p_tail,
704 p);
705 LOG (GNUNET_ERROR_TYPE_DEBUG,
706 "Peer %u (`%s') stopped\n",
707 p->no,
708 GNUNET_i2s (&p->id));
709 if (NULL != p->rh_task)
710 GNUNET_SCHEDULER_cancel (p->rh_task);
711 p->rh_task = NULL;
712 GNUNET_free (p);
713}
714
715
716/**
717 * Function called after the HELLO was passed to the
718 * transport service.
719 * FIXME maybe schedule the application_validate somehow
720 */
721/*
722 static void
723 hello_offered (void *cls)
724 {
725 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc = cls;
726
727 cc->oh = NULL;
728 cc->tct = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
729 &offer_hello,
730 cc);
731 }*/
732
733
734static void
735offer_hello (void *cls)
736{
737 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc = cls;
738 struct GNUNET_TRANSPORT_TESTING_PeerContext *p1 = cc->p1;
739 struct GNUNET_TRANSPORT_TESTING_PeerContext *p2 = cc->p2;
740 struct GNUNET_TIME_Absolute t;
741 enum GNUNET_NetworkType nt = 0;
742 char *addr;
743
744 cc->tct = NULL;
745 {
746 char *p2_s = GNUNET_strdup (GNUNET_i2s (&p2->id));
747
748 LOG (GNUNET_ERROR_TYPE_DEBUG,
749 "Asking peer %u (`%s') to connect peer %u (`%s'), providing HELLO with %s\n",
750 p1->no,
751 GNUNET_i2s (&p1->id),
752 p2->no,
753 p2_s,
754 p2->hello);
755 GNUNET_free (p2_s);
756 }
757
758 addr = GNUNET_HELLO_extract_address (p2->hello,
759 p2->hello_size,
760 &p2->id,
761 &nt,
762 &t);
763 GNUNET_assert (NULL != addr);
764 GNUNET_assert (NULL != p1->hello);
765 GNUNET_TRANSPORT_application_validate (p1->ah,
766 &p2->id,
767 nt,
768 addr);
769 GNUNET_free (addr);
770}
771
772
773/**
774 * Initiate a connection from p1 to p2 by offering p1 p2's HELLO message
775 *
776 * Remarks: start_peer's notify_connect callback can be called before.
777 *
778 * @param tth transport testing handle
779 * @param p1 peer 1
780 * @param p2 peer 2
781 * @param cb the callback to call when both peers notified that they are connected
782 * @param cls callback cls
783 * @return a connect request handle
784 */
785struct GNUNET_TRANSPORT_TESTING_ConnectRequest *
786GNUNET_TRANSPORT_TESTING_connect_peers (struct
787 GNUNET_TRANSPORT_TESTING_PeerContext *p1,
788 struct
789 GNUNET_TRANSPORT_TESTING_PeerContext *p2,
790 GNUNET_SCHEDULER_TaskCallback cb,
791 void *cls)
792{
793 struct GNUNET_TRANSPORT_TESTING_Handle *tth = p1->tth;
794 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
795 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn;
796
797 ccn = NULL;
798 for (cc = tth->cc_head; NULL != cc; cc = cc->next)
799 {
800 if ((cc->p1 == p1) &&
801 (cc->p2 == p2))
802 {
803 ccn = cc;
804 break;
805 }
806 }
807
808 cc = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_ConnectRequest);
809 cc->p1 = p1;
810 cc->p2 = p2;
811 cc->cb = cb;
812 if (NULL != cls)
813 cc->cb_cls = cls;
814 else
815 cc->cb_cls = cc;
816 if (NULL != ccn)
817 {
818 cc->p1_c = ccn->p1_c;
819 cc->p2_c = ccn->p2_c;
820 cc->connected = ccn->connected;
821 }
822 GNUNET_CONTAINER_DLL_insert (tth->cc_head,
823 tth->cc_tail,
824 cc);
825 cc->tct = GNUNET_SCHEDULER_add_now (&offer_hello,
826 cc);
827 cc->ats_sh = GNUNET_ATS_connectivity_suggest (cc->p1->ats,
828 &p2->id,
829 1);
830 LOG (GNUNET_ERROR_TYPE_DEBUG,
831 "New connect request %p\n",
832 cc);
833 return cc;
834}
835
836
837void
838GNUNET_TRANSPORT_TESTING_connect_peers_cancel (struct
839 GNUNET_TRANSPORT_TESTING_ConnectRequest
840 *cc)
841{
842 struct GNUNET_TRANSPORT_TESTING_Handle *tth = cc->p1->tth;
843
844 LOG (GNUNET_ERROR_TYPE_DEBUG,
845 "Canceling connect request!\n");
846 if (NULL != cc->tct)
847 {
848 GNUNET_SCHEDULER_cancel (cc->tct);
849 cc->tct = NULL;
850 }
851 if (NULL != cc->ats_sh)
852 {
853 GNUNET_ATS_connectivity_suggest_cancel (cc->ats_sh);
854 cc->ats_sh = NULL;
855 }
856 GNUNET_CONTAINER_DLL_remove (tth->cc_head,
857 tth->cc_tail,
858 cc);
859 GNUNET_free (cc);
860}
861
862
863/**
864 * Clean up the transport testing
865 *
866 * @param tth transport testing handle
867 */
868void
869GNUNET_TRANSPORT_TESTING_done (struct GNUNET_TRANSPORT_TESTING_Handle *tth)
870{
871 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
872 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ct;
873 struct GNUNET_TRANSPORT_TESTING_PeerContext *p;
874 struct GNUNET_TRANSPORT_TESTING_PeerContext *t;
875
876 if (NULL == tth)
877 return;
878 cc = tth->cc_head;
879 while (NULL != cc)
880 {
881 ct = cc->next;
882 LOG (GNUNET_ERROR_TYPE_ERROR,
883 "Developer forgot to cancel connect request!\n");
884 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc);
885 cc = ct;
886 }
887 p = tth->p_head;
888 while (NULL != p)
889 {
890 t = p->next;
891 LOG (GNUNET_ERROR_TYPE_ERROR,
892 "Developer forgot to stop peer!\n");
893 GNUNET_TRANSPORT_TESTING_stop_peer (p);
894 p = t;
895 }
896 GNUNET_TESTING_system_destroy (tth->tl_system,
897 GNUNET_YES);
898
899 GNUNET_free (tth);
900}
901
902
903/**
904 * Initialize the transport testing
905 *
906 * @return transport testing handle
907 */
908struct GNUNET_TRANSPORT_TESTING_Handle *
909GNUNET_TRANSPORT_TESTING_init ()
910{
911 struct GNUNET_TRANSPORT_TESTING_Handle *tth;
912
913 tth = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_Handle);
914 tth->tl_system = GNUNET_TESTING_system_create ("transport-testing",
915 NULL,
916 NULL,
917 NULL);
918 if (NULL == tth->tl_system)
919 {
920 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
921 "Failed to initialize testing library!\n");
922 GNUNET_free (tth);
923 return NULL;
924 }
925 return tth;
926}
927
928
929/* end of transport-testing.c */