aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/test_cadet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cadet/test_cadet.c')
-rw-r--r--src/cadet/test_cadet.c331
1 files changed, 251 insertions, 80 deletions
diff --git a/src/cadet/test_cadet.c b/src/cadet/test_cadet.c
index b9f177652..76ff258e0 100644
--- a/src/cadet/test_cadet.c
+++ b/src/cadet/test_cadet.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2011, 2017 GNUnet e.V. 3 Copyright (C) 2011, 2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file cadet/test_cadet.c 19 * @file cadet/test_cadet.c
@@ -72,6 +70,7 @@ struct CadetTestChannelWrapper
72#define SPEED_ACK 4 70#define SPEED_ACK 4
73#define SPEED_REL 8 71#define SPEED_REL 8
74#define P2P_SIGNAL 10 72#define P2P_SIGNAL 10
73#define REOPEN 11
75 74
76/** 75/**
77 * Which test are we running? 76 * Which test are we running?
@@ -179,6 +178,11 @@ struct GNUNET_CADET_TEST_Context *test_ctx;
179static struct GNUNET_SCHEDULER_Task *disconnect_task; 178static struct GNUNET_SCHEDULER_Task *disconnect_task;
180 179
181/** 180/**
181 * Task called to reconnect peers.
182 */
183static struct GNUNET_SCHEDULER_Task *reconnect_task;
184
185/**
182 * Task To perform tests 186 * Task To perform tests
183 */ 187 */
184static struct GNUNET_SCHEDULER_Task *test_task; 188static struct GNUNET_SCHEDULER_Task *test_task;
@@ -376,7 +380,8 @@ stats_cont (void *cls,
376 "KA sent: %u, KA received: %u\n", 380 "KA sent: %u, KA received: %u\n",
377 ka_sent, 381 ka_sent,
378 ka_received); 382 ka_received);
379 if ((KEEPALIVE == test) && ((ka_sent < 2) || (ka_sent > ka_received + 1))) 383 if ((KEEPALIVE == test || REOPEN == test) &&
384 ((ka_sent < 2) || (ka_sent > ka_received + 1)))
380 { 385 {
381 GNUNET_break (0); 386 GNUNET_break (0);
382 ok--; 387 ok--;
@@ -402,8 +407,11 @@ stats_cont (void *cls,
402 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration 407 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
403 */ 408 */
404static int 409static int
405stats_iterator (void *cls, const struct GNUNET_TESTBED_Peer *peer, 410stats_iterator (void *cls,
406 const char *subsystem, const char *name, uint64_t value, 411 const struct GNUNET_TESTBED_Peer *peer,
412 const char *subsystem,
413 const char *name,
414 uint64_t value,
407 int is_persistent) 415 int is_persistent)
408{ 416{
409 static const char *s_sent = "# keepalives sent"; 417 static const char *s_sent = "# keepalives sent";
@@ -458,6 +466,152 @@ gather_stats_and_exit (void *cls)
458 466
459 467
460/** 468/**
469 * Send a message on the channel with the appropriate size and payload.
470 *
471 * Update the appropriate *_sent counter.
472 *
473 * @param channel Channel to send the message on.
474 */
475static void
476send_test_message (struct GNUNET_CADET_Channel *channel);
477
478/**
479 * Check if payload is sane (size contains payload).
480 *
481 * @param cls should match #ch
482 * @param message The actual message.
483 * @return #GNUNET_OK to keep the channel open,
484 * #GNUNET_SYSERR to close it (signal serious error).
485 */
486static int
487check_data (void *cls,
488 const struct GNUNET_MessageHeader *message);
489
490/**
491 * Function is called whenever a message is received.
492 *
493 * @param cls closure (set from GNUNET_CADET_connect(), peer number)
494 * @param message the actual message
495 */
496static void
497handle_data (void *cls,
498 const struct GNUNET_MessageHeader *message);
499
500/**
501 * Function called whenever an MQ-channel is destroyed, even if the destruction
502 * was requested by #GNUNET_CADET_channel_destroy.
503 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
504 *
505 * It should clean up any associated state, including cancelling any pending
506 * transmission on this channel.
507 *
508 * @param cls Channel closure (channel wrapper).
509 * @param channel Connection to the other end (henceforth invalid).
510 */
511static void
512disconnect_handler (void *cls,
513 const struct GNUNET_CADET_Channel *channel);
514
515
516/**
517 * Task to reconnect to other peer.
518 *
519 * @param cls Closure (line from which the task was scheduled).
520 */
521static void
522reconnect_op (void *cls)
523{
524 struct GNUNET_MQ_MessageHandler handlers[] = {
525 GNUNET_MQ_hd_var_size (data,
526 GNUNET_MESSAGE_TYPE_DUMMY,
527 struct GNUNET_MessageHeader,
528 NULL),
529 GNUNET_MQ_handler_end ()
530 };
531 long l = (long) cls;
532 struct CadetTestChannelWrapper *ch;
533 enum GNUNET_CADET_ChannelOption flags;
534
535 reconnect_task = NULL;
536 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
537 "reconnecting from line %ld\n",
538 l);
539 if (NULL != outgoing_ch)
540 {
541 GNUNET_CADET_channel_destroy (outgoing_ch);
542 outgoing_ch = NULL;
543 }
544 flags = GNUNET_CADET_OPTION_DEFAULT;
545 ch = GNUNET_new (struct CadetTestChannelWrapper);
546 outgoing_ch = GNUNET_CADET_channel_create (h1,
547 ch,
548 p_id[1],
549 &port,
550 flags,
551 NULL,
552 &disconnect_handler,
553 handlers);
554 ch->ch = outgoing_ch;
555 send_test_message (outgoing_ch);
556}
557
558/**
559 * Function called whenever an MQ-channel is destroyed, even if the destruction
560 * was requested by #GNUNET_CADET_channel_destroy.
561 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
562 *
563 * It should clean up any associated state, including cancelling any pending
564 * transmission on this channel.
565 *
566 * @param cls Channel closure (channel wrapper).
567 * @param channel Connection to the other end (henceforth invalid).
568 */
569static void
570disconnect_handler (void *cls,
571 const struct GNUNET_CADET_Channel *channel)
572{
573 struct CadetTestChannelWrapper *ch_w = cls;
574
575 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
576 "Channel disconnected at %d\n",
577 ok);
578 GNUNET_assert (ch_w->ch == channel);
579 if (channel == incoming_ch)
580 {
581 ok++;
582 incoming_ch = NULL;
583 }
584 else if (outgoing_ch == channel)
585 {
586 if (P2P_SIGNAL == test)
587 {
588 ok++;
589 }
590 outgoing_ch = NULL;
591 }
592 else
593 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
594 "Unknown channel! %p\n",
595 channel);
596 if (NULL != disconnect_task && REOPEN != test)
597 {
598 GNUNET_SCHEDULER_cancel (disconnect_task);
599 disconnect_task =
600 GNUNET_SCHEDULER_add_now (&gather_stats_and_exit,
601 (void *) __LINE__);
602 }
603 else if (NULL != reconnect_task && REOPEN == test)
604 {
605 GNUNET_SCHEDULER_cancel (reconnect_task);
606 reconnect_task =
607 GNUNET_SCHEDULER_add_now (&reconnect_op,
608 (void *) __LINE__);
609 }
610 GNUNET_free (ch_w);
611}
612
613
614/**
461 * Abort test: schedule disconnect and shutdown immediately 615 * Abort test: schedule disconnect and shutdown immediately
462 * 616 *
463 * @param line Line in the code the abort is requested from (__LINE__). 617 * @param line Line in the code the abort is requested from (__LINE__).
@@ -535,6 +689,14 @@ send_test_message (struct GNUNET_CADET_Channel *channel)
535 { 689 {
536 payload = data_sent; 690 payload = data_sent;
537 } 691 }
692 else if (REOPEN == test)
693 {
694 payload = data_sent;
695 data_sent++;
696 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
697 "Sending DATA %u [%d bytes]\n",
698 data_sent, size);
699 }
538 else 700 else
539 { 701 {
540 GNUNET_assert (0); 702 GNUNET_assert (0);
@@ -614,10 +776,9 @@ reschedule_timeout_task (long line)
614 * #GNUNET_SYSERR to close it (signal serious error). 776 * #GNUNET_SYSERR to close it (signal serious error).
615 */ 777 */
616static int 778static int
617check_data (void *cls, const struct GNUNET_MessageHeader *message) 779check_data (void *cls,
780 const struct GNUNET_MessageHeader *message)
618{ 781{
619 if (sizeof (struct GNUNET_MessageHeader) >= ntohs (message->size))
620 return GNUNET_SYSERR;
621 return GNUNET_OK; /* all is well-formed */ 782 return GNUNET_OK; /* all is well-formed */
622} 783}
623 784
@@ -646,24 +807,33 @@ handle_data (void *cls,
646 807
647 if (channel == outgoing_ch) 808 if (channel == outgoing_ch)
648 { 809 {
649 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Root client got a message.\n"); 810 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
811 "Root client got a message.\n");
650 } 812 }
651 else if (channel == incoming_ch) 813 else if (channel == incoming_ch)
652 { 814 {
653 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Leaf client got a message.\n"); 815 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
816 "Leaf client got a message.\n");
654 } 817 }
655 else 818 else
656 { 819 {
657 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unknown channel %p.\n", channel); 820 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
821 "Unknown channel %p.\n",
822 channel);
658 GNUNET_assert (0); 823 GNUNET_assert (0);
659 } 824 }
660 825
661 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: (%d/%d)\n", ok, ok_goal); 826 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
827 " ok: (%d/%d)\n",
828 ok,
829 ok_goal);
662 data = (uint32_t *) &message[1]; 830 data = (uint32_t *) &message[1];
663 payload = ntohl (*data); 831 payload = ntohl (*data);
664 if (payload == *counter) 832 if (payload == *counter)
665 { 833 {
666 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " payload as expected: %u\n", payload); 834 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
835 " payload as expected: %u\n",
836 payload);
667 } 837 }
668 else 838 else
669 { 839 {
@@ -679,7 +849,8 @@ handle_data (void *cls,
679 if (SPEED == test) 849 if (SPEED == test)
680 { 850 {
681 GNUNET_assert (incoming_ch == channel); 851 GNUNET_assert (incoming_ch == channel);
682 send_next_msg_task = GNUNET_SCHEDULER_add_now (&send_next_msg, NULL); 852 send_next_msg_task = GNUNET_SCHEDULER_add_now (&send_next_msg,
853 NULL);
683 return; 854 return;
684 } 855 }
685 } 856 }
@@ -740,7 +911,8 @@ handle_data (void *cls,
740 * received on the @a channel. 911 * received on the @a channel.
741 */ 912 */
742static void * 913static void *
743connect_handler (void *cls, struct GNUNET_CADET_Channel *channel, 914connect_handler (void *cls,
915 struct GNUNET_CADET_Channel *channel,
744 const struct GNUNET_PeerIdentity *source) 916 const struct GNUNET_PeerIdentity *source)
745{ 917{
746 struct CadetTestChannelWrapper *ch; 918 struct CadetTestChannelWrapper *ch;
@@ -748,15 +920,20 @@ connect_handler (void *cls, struct GNUNET_CADET_Channel *channel,
748 920
749 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 921 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
750 "Incoming channel from %s to %ld: %p\n", 922 "Incoming channel from %s to %ld: %p\n",
751 GNUNET_i2s (source), peer, channel); 923 GNUNET_i2s (source),
924 peer,
925 channel);
752 ok++; 926 ok++;
753 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok); 927 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
928 " ok: %d\n",
929 ok);
754 if (peer == peers_requested - 1) 930 if (peer == peers_requested - 1)
755 { 931 {
756 if (NULL != incoming_ch) 932 if (NULL != incoming_ch)
757 { 933 {
758 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 934 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
759 "Duplicate incoming channel for client %lu\n", (long) cls); 935 "Duplicate incoming channel for client %lu\n",
936 (long) cls);
760 GNUNET_assert (0); 937 GNUNET_assert (0);
761 } 938 }
762 incoming_ch = channel; 939 incoming_ch = channel;
@@ -764,16 +941,33 @@ connect_handler (void *cls, struct GNUNET_CADET_Channel *channel,
764 else 941 else
765 { 942 {
766 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 943 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
767 "Incoming channel for unexpected peer #%lu\n", (long) cls); 944 "Incoming channel for unexpected peer #%lu\n",
945 (long) cls);
768 GNUNET_assert (0); 946 GNUNET_assert (0);
769 } 947 }
770 if (NULL != disconnect_task) 948 if (NULL != disconnect_task && REOPEN != test)
771 { 949 {
772 GNUNET_SCHEDULER_cancel (disconnect_task); 950 GNUNET_SCHEDULER_cancel (disconnect_task);
773 disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time, 951 disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
774 &gather_stats_and_exit, 952 &gather_stats_and_exit,
775 (void *) __LINE__); 953 (void *) __LINE__);
776 } 954 }
955 else if ((NULL != disconnect_task) && (REOPEN == test))
956 {
957 GNUNET_SCHEDULER_cancel (disconnect_task);
958 disconnect_task = GNUNET_SCHEDULER_add_delayed (
959 GNUNET_TIME_relative_multiply (short_time, 2),
960 &gather_stats_and_exit,
961 (void *) __LINE__);
962 }
963
964 if ((NULL != reconnect_task) && (REOPEN == test))
965 {
966 GNUNET_SCHEDULER_cancel (reconnect_task);
967 reconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
968 &reconnect_op,
969 (void *) __LINE__);
970 }
777 971
778 /* TODO: cannot return channel as-is, in order to unify the data handlers */ 972 /* TODO: cannot return channel as-is, in order to unify the data handlers */
779 ch = GNUNET_new (struct CadetTestChannelWrapper); 973 ch = GNUNET_new (struct CadetTestChannelWrapper);
@@ -784,55 +978,6 @@ connect_handler (void *cls, struct GNUNET_CADET_Channel *channel,
784 978
785 979
786/** 980/**
787 * Function called whenever an MQ-channel is destroyed, even if the destruction
788 * was requested by #GNUNET_CADET_channel_destroy.
789 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
790 *
791 * It should clean up any associated state, including cancelling any pending
792 * transmission on this channel.
793 *
794 * @param cls Channel closure (channel wrapper).
795 * @param channel Connection to the other end (henceforth invalid).
796 */
797static void
798disconnect_handler (void *cls,
799 const struct GNUNET_CADET_Channel *channel)
800{
801 struct CadetTestChannelWrapper *ch_w = cls;
802
803 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
804 "Channel disconnected at %d\n",
805 ok);
806 GNUNET_assert (ch_w->ch == channel);
807 if (channel == incoming_ch)
808 {
809 ok++;
810 incoming_ch = NULL;
811 }
812 else if (outgoing_ch == channel)
813 {
814 if (P2P_SIGNAL == test)
815 {
816 ok++;
817 }
818 outgoing_ch = NULL;
819 }
820 else
821 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
822 "Unknown channel! %p\n",
823 channel);
824 if (NULL != disconnect_task)
825 {
826 GNUNET_SCHEDULER_cancel (disconnect_task);
827 disconnect_task =
828 GNUNET_SCHEDULER_add_now (&gather_stats_and_exit,
829 (void *) __LINE__);
830 }
831 GNUNET_free (ch_w);
832}
833
834
835/**
836 * START THE TESTCASE ITSELF, AS WE ARE CONNECTED TO THE CADET SERVICES. 981 * START THE TESTCASE ITSELF, AS WE ARE CONNECTED TO THE CADET SERVICES.
837 * 982 *
838 * Testcase continues when the root receives confirmation of connected peers, 983 * Testcase continues when the root receives confirmation of connected peers,
@@ -854,7 +999,7 @@ start_test (void *cls)
854 enum GNUNET_CADET_ChannelOption flags; 999 enum GNUNET_CADET_ChannelOption flags;
855 1000
856 test_task = NULL; 1001 test_task = NULL;
857 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "start_test\n"); 1002 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "start_test: %s\n", test_name);
858 if (NULL != disconnect_task) 1003 if (NULL != disconnect_task)
859 { 1004 {
860 GNUNET_SCHEDULER_cancel (disconnect_task); 1005 GNUNET_SCHEDULER_cancel (disconnect_task);
@@ -886,7 +1031,6 @@ start_test (void *cls)
886 if (KEEPALIVE == test) 1031 if (KEEPALIVE == test)
887 return; /* Don't send any data. */ 1032 return; /* Don't send any data. */
888 1033
889
890 data_received = 0; 1034 data_received = 0;
891 data_sent = 0; 1035 data_sent = 0;
892 ack_received = 0; 1036 ack_received = 0;
@@ -895,6 +1039,18 @@ start_test (void *cls)
895 "Sending data initializer on channel %p...\n", 1039 "Sending data initializer on channel %p...\n",
896 outgoing_ch); 1040 outgoing_ch);
897 send_test_message (outgoing_ch); 1041 send_test_message (outgoing_ch);
1042 if (REOPEN == test)
1043 {
1044 reconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
1045 &reconnect_op,
1046 (void *) __LINE__);
1047 GNUNET_SCHEDULER_cancel (disconnect_task);
1048 disconnect_task = GNUNET_SCHEDULER_add_delayed (
1049 GNUNET_TIME_relative_multiply (short_time, 2),
1050 &gather_stats_and_exit,
1051 (void *) __LINE__);
1052 }
1053
898} 1054}
899 1055
900 1056
@@ -1003,7 +1159,6 @@ main (int argc, char *argv[])
1003 "short_time", 1159 "short_time",
1004 gettext_noop ("set short timeout"), 1160 gettext_noop ("set short timeout"),
1005 &short_time), 1161 &short_time),
1006
1007 GNUNET_GETOPT_option_uint ('m', 1162 GNUNET_GETOPT_option_uint ('m',
1008 "messages", 1163 "messages",
1009 "NUM_MESSAGES", 1164 "NUM_MESSAGES",
@@ -1039,6 +1194,11 @@ main (int argc, char *argv[])
1039 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "5 PEER LINE\n"); 1194 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "5 PEER LINE\n");
1040 peers_requested = 5; 1195 peers_requested = 5;
1041 } 1196 }
1197 else if (strstr (argv[0], "_6_") != NULL)
1198 {
1199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "6 PEER LINE\n");
1200 peers_requested = 6;
1201 }
1042 else 1202 else
1043 { 1203 {
1044 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "SIZE UNKNOWN, USING 2\n"); 1204 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "SIZE UNKNOWN, USING 2\n");
@@ -1106,6 +1266,17 @@ main (int argc, char *argv[])
1106 */ 1266 */
1107 ok_goal = 2; 1267 ok_goal = 2;
1108 } 1268 }
1269 else if (strstr (argv[0], "_reopen") != NULL)
1270 {
1271 test = REOPEN;
1272 test_name = "reopen";
1273 ///* Test is supposed to generate the following callbacks:
1274 // * 1 incoming channel (@dest)
1275 // * [wait]
1276 // * 1 received channel destroy (@dest)
1277 // */
1278 ok_goal = 7;
1279 }
1109 else 1280 else
1110 { 1281 {
1111 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "UNKNOWN\n"); 1282 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "UNKNOWN\n");