aboutsummaryrefslogtreecommitdiff
path: root/src/transport/test_plugin_transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/test_plugin_transport.c')
-rw-r--r--src/transport/test_plugin_transport.c797
1 files changed, 0 insertions, 797 deletions
diff --git a/src/transport/test_plugin_transport.c b/src/transport/test_plugin_transport.c
deleted file mode 100644
index 04687d845..000000000
--- a/src/transport/test_plugin_transport.c
+++ /dev/null
@@ -1,797 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2018 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/test_plugin_transport.c
22 * @brief testcase for transport_api.c
23 * @author Sailor Siraj
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_hello_lib.h"
30#include "gnunet_peerinfo_service.h"
31#include "gnunet_statistics_service.h"
32#include "gnunet_protocols.h"
33#include "gnunet_transport_plugin.h"
34#include "transport.h"
35
36/**
37 * How long until we give up on transmitting the message?
38 */
39#define WAIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
40#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
41
42#define HOSTKEY_FILE "test_plugin_hostkey.ecc"
43
44/**
45 * Our public key.
46 */
47static struct GNUNET_PeerIdentity my_identity;
48
49/**
50 * Our private key.
51 */
52static struct GNUNET_CRYPTO_EddsaPrivateKey my_private_key;
53
54/**
55 * Our configuration.
56 */
57const struct GNUNET_CONFIGURATION_Handle *cfg;
58
59/**
60 * Our configuration.
61 */
62struct GNUNET_STATISTICS_Handle *stats;
63
64/**
65 * Our HELLO
66 */
67struct GNUNET_HELLO_Message *hello;
68
69/**
70 * Number of neighbours we'd like to have.
71 */
72static uint32_t max_connect_per_transport;
73
74/**
75 * Environment for this plugin.
76 */
77struct GNUNET_TRANSPORT_PluginEnvironment env;
78
79/**
80 * handle for the api provided by this plugin
81 */
82struct GNUNET_TRANSPORT_PluginFunctions *api;
83
84/**
85 * Helper handler
86 */
87struct GNUNET_HELPER_Handle *suid_helper;
88
89/**
90 * Timeout task
91 */
92static struct GNUNET_SCHEDULER_Task *timeout_endbadly;
93
94/**
95 * Timeout task
96 */
97static struct GNUNET_SCHEDULER_Task *timeout_wait;
98
99/**
100 * Library name
101 */
102static char *libname;
103
104/**
105 * Plugin addresses head
106 */
107struct AddressWrapper *head;
108
109/**
110 * Plugin addresses tail
111 */
112struct AddressWrapper *tail;
113
114unsigned int addresses_reported;
115
116unsigned int pretty_printers_running;
117
118/**
119 * Did the test pass or fail?
120 */
121static int ok;
122
123struct AddressWrapper
124{
125 struct AddressWrapper *next;
126
127 struct AddressWrapper *prev;
128
129 struct GNUNET_HELLO_Address *address;
130
131 char *addrstring;
132
133 struct GNUNET_SCHEDULER_Task *test_task;
134};
135
136
137static void
138end ()
139{
140 struct AddressWrapper *w;
141 int c = 0;
142
143 ok = 0;
144
145 if (NULL != timeout_endbadly)
146 {
147 GNUNET_SCHEDULER_cancel (timeout_endbadly);
148 timeout_endbadly = NULL;
149 }
150 if (NULL != api)
151 GNUNET_PLUGIN_unload (libname, api);
152
153 while (NULL != head)
154 {
155 w = head;
156 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
157 "Plugin did not remove address `%s'\n",
158 w->addrstring);
159 GNUNET_CONTAINER_DLL_remove (head, tail, w);
160 c++;
161 GNUNET_HELLO_address_free (w->address);
162 GNUNET_free (w->addrstring);
163 GNUNET_free (w);
164 }
165 if (c > 0)
166 {
167 GNUNET_break (0);
168 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
169 "Plugin did not remove %u addresses \n",
170 c);
171 ok = 1;
172 }
173
174 GNUNET_free (libname);
175 libname = NULL;
176 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
177 stats = NULL;
178
179 if (NULL != suid_helper)
180 {
181 GNUNET_HELPER_stop (suid_helper, GNUNET_NO);
182 suid_helper = NULL;
183 }
184}
185
186
187static void
188end_badly (void *cls)
189{
190 struct AddressWrapper *w;
191 int c = 0;
192
193 timeout_endbadly = NULL;
194 if (NULL != timeout_wait)
195 {
196 GNUNET_SCHEDULER_cancel (timeout_wait);
197 timeout_wait = NULL;
198 }
199
200 if (pretty_printers_running > 0)
201 {
202 timeout_endbadly = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
203 &end_badly, &ok);
204 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
205 "Have pending calls to pretty_printer ... deferring shutdown\n");
206 return;
207 }
208
209 if (NULL != cls)
210 {
211 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
212 "Test took too long to execute, timeout .... \n");
213 }
214
215 if (NULL != libname)
216 {
217 if (NULL != api)
218 GNUNET_PLUGIN_unload (libname, api);
219 GNUNET_free (libname);
220 libname = NULL;
221 }
222
223 while (NULL != head)
224 {
225 w = head;
226 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Plugin did not remove address `%s'\n",
227 w->addrstring);
228 GNUNET_CONTAINER_DLL_remove (head, tail, w);
229 c++;
230 GNUNET_HELLO_address_free (w->address);
231 if (NULL != w->test_task)
232 GNUNET_SCHEDULER_cancel (w->test_task);
233 GNUNET_free (w->addrstring);
234 GNUNET_free (w);
235 }
236 if (c > 0)
237 {
238 GNUNET_break (0);
239 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Plugin did not remove %u addresses\n",
240 c);
241 }
242
243 if (NULL != stats)
244 {
245 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
246 stats = NULL;
247 }
248
249 if (NULL != suid_helper)
250 {
251 GNUNET_HELPER_stop (suid_helper, GNUNET_NO);
252 suid_helper = NULL;
253 }
254
255 ok = 1;
256}
257
258
259static void
260wait_end (void *cls)
261{
262 timeout_wait = NULL;
263 if (0 == addresses_reported)
264 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
265 "Plugin did not report any addresses, could not check address conversion functions\n");
266 end ();
267}
268
269
270static void
271end_badly_now ()
272{
273 if (NULL != timeout_wait)
274 {
275 GNUNET_SCHEDULER_cancel (timeout_wait);
276 timeout_wait = NULL;
277 }
278 if (NULL != timeout_endbadly)
279 {
280 GNUNET_SCHEDULER_cancel (timeout_endbadly);
281 timeout_endbadly = NULL;
282 }
283 timeout_endbadly = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
284}
285
286
287static struct GNUNET_TIME_Relative
288env_receive (void *cls,
289 const struct GNUNET_HELLO_Address *address,
290 struct GNUNET_ATS_Session *session,
291 const struct GNUNET_MessageHeader *message)
292{
293 /* do nothing */
294 return GNUNET_TIME_relative_get_zero_ ();
295}
296
297
298static int got_reply;
299
300
301/**
302 * Take the given address and append it to the set of results sent back to
303 * the client.
304 *
305 * @param cls closure
306 * @param address the address to print
307 * @param res result code
308 */
309static void
310address_pretty_printer_cb (void *cls, const char *address, int res)
311{
312 if (NULL != address)
313 {
314 got_reply = GNUNET_YES;
315 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Pretty address : `%s'\n", address);
316 pretty_printers_running--;
317 }
318 else
319 {
320 if (GNUNET_NO == got_reply)
321 {
322 pretty_printers_running--;
323 GNUNET_break (0);
324 end_badly_now ();
325 }
326 }
327}
328
329
330static void
331test_addr_string (void *cls)
332{
333 struct AddressWrapper *w = cls;
334 void *s2a;
335 size_t s2a_len;
336
337 w->test_task = NULL;
338
339 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
340 "Testing: address_to_string \n");
341 w->addrstring = GNUNET_strdup (api->address_to_string (api,
342 w->address->address,
343 w->address->
344 address_length));
345 if (NULL == w->addrstring)
346 {
347 GNUNET_break (0);
348 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
349 "Plugin cannot convert address to string!\n");
350 end_badly_now ();
351 return;
352 }
353 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
354 "Plugin added address `%s'\n",
355 w->addrstring);
356 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
357 "Testing address_to_string: OK\n");
358 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
359 "Testing: string_to_address \n");
360 s2a = NULL;
361 s2a_len = 0;
362 if ((GNUNET_OK !=
363 api->string_to_address (api, w->addrstring,
364 strlen (w->addrstring) + 1,
365 &s2a, &s2a_len)) ||
366 (NULL == s2a))
367 {
368 GNUNET_break (0);
369 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
370 "Plugin cannot convert string to address!\n");
371 end_badly_now ();
372 return;
373 }
374
375 /*
376 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
377 "Plugin creates `%s' %u\n",api->address_to_string (api, s2a, s2a_len), s2a_len);
378
379 int c1;
380 for (c1 = 0; c1 < s2a_len; c1++ )
381 fprintf (stderr, "%u == %u\n", ((char *) s2a)[c1], ((char *) w->addr)[c1]);
382 */if (s2a_len != w->address->address_length)
383 {
384 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
385 "Plugin creates different address length when converting address->string->address: %u != %u\n",
386 (unsigned int) w->address->address_length,
387 (unsigned int) s2a_len);
388 }
389 else if (0 != memcmp (s2a, w->address->address, s2a_len))
390 {
391 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
392 "Plugin creates different address length when converting back and forth %i!\n",
393 memcmp (s2a,
394 w->address->address,
395 s2a_len));
396 }
397 else
398 {
399 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
400 "Testing string_to_address: OK\n");
401 }
402 GNUNET_free (s2a);
403
404 pretty_printers_running++;
405 api->address_pretty_printer (api->cls,
406 w->address->transport_name,
407 w->address->address,
408 w->address->address_length,
409 GNUNET_YES,
410 GNUNET_TIME_UNIT_MINUTES,
411 &address_pretty_printer_cb, w);
412
413 if (GNUNET_OK !=
414 api->check_address (api->cls,
415 w->address->address,
416 w->address->address_length))
417 {
418 GNUNET_break (0);
419 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
420 "Plugin refuses added address!\n");
421 end_badly_now ();
422 return;
423 }
424 if (NULL != timeout_wait)
425 {
426 GNUNET_SCHEDULER_cancel (timeout_wait);
427 timeout_wait = NULL;
428 }
429 timeout_wait = GNUNET_SCHEDULER_add_delayed (WAIT, &wait_end, NULL);
430}
431
432
433static void
434env_notify_address (void *cls,
435 int add_remove,
436 const struct GNUNET_HELLO_Address *address)
437{
438 struct AddressWrapper *w;
439 struct AddressWrapper *wtmp;
440
441 if (GNUNET_YES == add_remove)
442 {
443 addresses_reported++;
444 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
445 "Adding address of length %u\n",
446 (unsigned int) address->address_length);
447
448 for (wtmp = head; NULL != wtmp; wtmp = wtmp->next)
449 {
450 if ((address->address_length == wtmp->address->address_length) &&
451 (0 == memcmp (address->address, wtmp->address->address,
452 address->address_length)))
453 {
454 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
455 "Duplicate address notification .... \n");
456 return;
457 }
458 }
459
460 w = GNUNET_new (struct AddressWrapper);
461 w->address = GNUNET_HELLO_address_copy (address);
462 GNUNET_CONTAINER_DLL_insert (head, tail, w);
463 got_reply = GNUNET_NO;
464 w->test_task = GNUNET_SCHEDULER_add_now (&test_addr_string,
465 w);
466 return;
467 }
468
469 if (GNUNET_NO == add_remove)
470 {
471 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
472 "Removing address of length %u\n",
473 (unsigned int) address->address_length);
474 w = head;
475 while (NULL != w)
476 {
477 if ((address->address_length == w->address->address_length) &&
478 (0 == memcmp (w->address->address, address->address,
479 address->address_length)))
480 {
481 break;
482 }
483 w = w->next;
484 }
485
486 if (w == NULL)
487 {
488 GNUNET_break (0);
489 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
490 "Plugin removes address never added!\n");
491 end_badly_now ();
492 return;
493 }
494
495 GNUNET_CONTAINER_DLL_remove (head, tail, w);
496 GNUNET_HELLO_address_free (w->address);
497 GNUNET_free (w->addrstring);
498 GNUNET_free (w);
499 return;
500 }
501 GNUNET_break (0);
502 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
503 "Invalid operation: %u\n",
504 add_remove);
505 end_badly_now ();
506}
507
508
509static enum GNUNET_NetworkType
510env_get_address_type (void *cls,
511 const struct sockaddr *addr,
512 size_t addrlen)
513{
514 return GNUNET_NT_LOOPBACK;
515}
516
517
518static const struct GNUNET_MessageHeader *
519env_get_our_hello ()
520{
521 return (const struct GNUNET_MessageHeader *) hello;
522}
523
524
525static void
526env_session_end (void *cls,
527 const struct GNUNET_HELLO_Address *address,
528 struct GNUNET_ATS_Session *session)
529{
530}
531
532
533static void
534env_update_distance (void *cls,
535 const struct GNUNET_HELLO_Address *address,
536 uint32_t distance)
537{
538}
539
540
541static void
542setup_plugin_environment ()
543{
544 env.cfg = cfg;
545 env.cls = &env;
546 env.my_identity = &my_identity;
547 env.max_connections = max_connect_per_transport;
548 env.stats = stats;
549 env.receive = &env_receive;
550 env.notify_address = &env_notify_address;
551 env.get_address_type = &env_get_address_type;
552 env.update_address_distance = &env_update_distance;
553 env.get_our_hello = &env_get_our_hello;
554 env.session_end = &env_session_end;
555}
556
557
558static int
559handle_helper_message (void *cls,
560 const struct GNUNET_MessageHeader *hdr)
561{
562 return GNUNET_OK;
563}
564
565
566/**
567 * Runs the test.
568 *
569 * @param cls closure
570 * @param c configuration to use
571 */
572static void
573run (void *cls,
574 char *const *args,
575 const char *cfgfile,
576 const struct GNUNET_CONFIGURATION_Handle *c)
577{
578 char *const *argv = cls;
579 unsigned long long tneigh;
580 char *keyfile;
581 char *plugin;
582 char *sep;
583
584 timeout_endbadly = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
585 &end_badly,
586 &ok);
587 cfg = c;
588 /* parse configuration */
589 if ((GNUNET_OK !=
590 GNUNET_CONFIGURATION_get_value_number (c,
591 "TRANSPORT",
592 "NEIGHBOUR_LIMIT",
593 &tneigh)) ||
594 (GNUNET_OK !=
595 GNUNET_CONFIGURATION_get_value_filename (c,
596 "PEER",
597 "PRIVATE_KEY",
598 &keyfile)))
599 {
600 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
601 "Transport service is lacking key configuration settings. Exiting.\n");
602 return;
603 }
604
605 if (NULL == (stats = GNUNET_STATISTICS_create ("transport",
606 cfg)))
607 {
608 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
609 "Could not create statistics. Exiting.\n");
610 GNUNET_free (keyfile);
611 end_badly_now ();
612 return;
613 }
614
615 if (GNUNET_OK != GNUNET_DISK_file_test (HOSTKEY_FILE))
616 {
617 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
618 "Hostkey `%s' missing. Exiting.\n",
619 HOSTKEY_FILE);
620 GNUNET_free (keyfile);
621 end_badly_now ();
622 return;
623 }
624
625 if (GNUNET_OK !=
626 GNUNET_DISK_directory_create_for_file (keyfile))
627 {
628 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
629 "Could not create a directory for hostkey `%s'. Exiting.\n",
630 keyfile);
631 GNUNET_free (keyfile);
632 end_badly_now ();
633 return;
634 }
635
636 if (GNUNET_OK !=
637 GNUNET_DISK_file_copy (HOSTKEY_FILE,
638 keyfile))
639 {
640 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
641 "Could not copy hostkey `%s' to destination `%s'. Exiting.\n",
642 HOSTKEY_FILE,
643 keyfile);
644 GNUNET_free (keyfile);
645 end_badly_now ();
646 return;
647 }
648
649 max_connect_per_transport = (uint32_t) tneigh;
650 if (GNUNET_SYSERR ==
651 GNUNET_CRYPTO_eddsa_key_from_file (keyfile,
652 GNUNET_YES,
653 &my_private_key))
654 {
655 GNUNET_free (keyfile);
656 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
657 "Could not access hostkey. Exiting.\n");
658 end_badly_now ();
659 return;
660 }
661 GNUNET_free (keyfile);
662 GNUNET_CRYPTO_eddsa_key_get_public (&my_private_key,
663 &my_identity.public_key);
664
665 hello = GNUNET_HELLO_create (&my_identity.public_key, NULL, NULL, GNUNET_NO);
666
667 /* load plugins... */
668 setup_plugin_environment ();
669
670 GNUNET_assert (strlen (argv[0]) > strlen ("test_plugin_"));
671 plugin = strstr (argv[0], "test_plugin_");
672 sep = strrchr (argv[0], '.');
673 if (NULL == plugin)
674 {
675 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Not a valid test name\n");
676 end_badly_now ();
677 return;
678 }
679 plugin += strlen ("test_plugin_");
680 if (NULL != sep)
681 sep[0] = '\0';
682
683 /* Hack for WLAN: start a second helper */
684 if (0 == strcmp (plugin, "wlan"))
685 {
686 char *helper_argv[3];
687 helper_argv[0] = (char *) "gnunet-helper-transport-wlan-dummy";
688 helper_argv[1] = (char *) "2";
689 helper_argv[2] = NULL;
690 suid_helper = GNUNET_HELPER_start (GNUNET_NO,
691 "gnunet-helper-transport-wlan-dummy",
692 helper_argv,
693 &handle_helper_message, NULL, NULL);
694 }
695
696 /* Loading plugin */
697 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Loading transport plugin %s\n", plugin);
698 GNUNET_asprintf (&libname, "libgnunet_plugin_transport_%s", plugin);
699 api = GNUNET_PLUGIN_load (libname, &env);
700 if (NULL == api)
701 {
702 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
703 "Failed to load transport plugin for %s\n", plugin);
704 end_badly_now ();
705 return;
706 }
707
708 timeout_wait = GNUNET_SCHEDULER_add_delayed (WAIT, &wait_end, NULL);
709
710 /* Check if all functions are implemented */
711 if (NULL == api->address_pretty_printer)
712 {
713 GNUNET_break (0);
714 end_badly_now ();
715 return;
716 }
717 if (NULL == api->address_to_string)
718 {
719 GNUNET_break (0);
720 end_badly_now ();
721 return;
722 }
723 GNUNET_assert (NULL != api->check_address);
724 if (NULL == api->check_address)
725 {
726 GNUNET_break (0);
727 end_badly_now ();
728 return;
729 }
730 GNUNET_assert (NULL != api->disconnect_peer);
731 if (NULL == api->disconnect_peer)
732 {
733 GNUNET_break (0);
734 end_badly_now ();
735 return;
736 }
737 GNUNET_assert (NULL != api->get_session);
738 if (NULL == api->get_session)
739 {
740 GNUNET_break (0);
741 end_badly_now ();
742 return;
743 }
744 if (NULL == api->address_pretty_printer)
745 {
746 GNUNET_break (0);
747 end_badly_now ();
748 return;
749 }
750 if (NULL == api->string_to_address)
751 {
752 GNUNET_break (0);
753 end_badly_now ();
754 return;
755 }
756}
757
758
759/**
760 * The main function for the test
761 *
762 * @param argc number of arguments from the command line
763 * @param argv command line arguments
764 * @return 0 ok, 1 on error
765 */
766int
767main (int argc,
768 char *const *argv)
769{
770 static struct GNUNET_GETOPT_CommandLineOption options[] = {
771 GNUNET_GETOPT_OPTION_END
772 };
773 int ret;
774 char *const argv_prog[] = {
775 "test_plugin_transport",
776 "-c",
777 "test_plugin_transport_data.conf",
778 NULL
779 };
780
781 GNUNET_log_setup ("test-plugin-transport",
782 "WARNING",
783 NULL);
784 GNUNET_DISK_purge_cfg_dir ("test_plugin_transport_data.conf",
785 "GNUNET_TEST_HOME");
786 ok = 1; /* set to fail */
787 ret =
788 (GNUNET_OK
789 == GNUNET_PROGRAM_run (3, argv_prog, "test-plugin-transport",
790 "testcase", options, &run, (void *) argv)) ? ok : 1;
791 GNUNET_DISK_purge_cfg_dir ("test_plugin_transport_data.conf",
792 "GNUNET_TEST_HOME");
793 return ret;
794}
795
796
797/* end of test_plugin_transport.c */