Copyright (C) 2011, 2017 GNUnet e.V.
GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published
+ under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
*/
/**
* @file cadet/test_cadet.c
#define SPEED_ACK 4
#define SPEED_REL 8
#define P2P_SIGNAL 10
+#define REOPEN 11
/**
* Which test are we running?
*/
static struct GNUNET_SCHEDULER_Task *disconnect_task;
+/**
+ * Task called to reconnect peers.
+ */
+static struct GNUNET_SCHEDULER_Task *reconnect_task;
+
/**
* Task To perform tests
*/
"KA sent: %u, KA received: %u\n",
ka_sent,
ka_received);
- if ((KEEPALIVE == test) && ((ka_sent < 2) || (ka_sent > ka_received + 1)))
+ if ((KEEPALIVE == test || REOPEN == test) &&
+ ((ka_sent < 2) || (ka_sent > ka_received + 1)))
{
GNUNET_break (0);
ok--;
}
+/**
+ * Send a message on the channel with the appropriate size and payload.
+ *
+ * Update the appropriate *_sent counter.
+ *
+ * @param channel Channel to send the message on.
+ */
+static void
+send_test_message (struct GNUNET_CADET_Channel *channel);
+
+/**
+ * Check if payload is sane (size contains payload).
+ *
+ * @param cls should match #ch
+ * @param message The actual message.
+ * @return #GNUNET_OK to keep the channel open,
+ * #GNUNET_SYSERR to close it (signal serious error).
+ */
+static int
+check_data (void *cls,
+ const struct GNUNET_MessageHeader *message);
+
+/**
+ * Function is called whenever a message is received.
+ *
+ * @param cls closure (set from GNUNET_CADET_connect(), peer number)
+ * @param message the actual message
+ */
+static void
+handle_data (void *cls,
+ const struct GNUNET_MessageHeader *message);
+
+/**
+ * Function called whenever an MQ-channel is destroyed, even if the destruction
+ * was requested by #GNUNET_CADET_channel_destroy.
+ * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
+ *
+ * It should clean up any associated state, including cancelling any pending
+ * transmission on this channel.
+ *
+ * @param cls Channel closure (channel wrapper).
+ * @param channel Connection to the other end (henceforth invalid).
+ */
+static void
+disconnect_handler (void *cls,
+ const struct GNUNET_CADET_Channel *channel);
+
+
+/**
+ * Task to reconnect to other peer.
+ *
+ * @param cls Closure (line from which the task was scheduled).
+ */
+static void
+reconnect_op (void *cls)
+{
+ struct GNUNET_MQ_MessageHandler handlers[] = {
+ GNUNET_MQ_hd_var_size (data,
+ GNUNET_MESSAGE_TYPE_DUMMY,
+ struct GNUNET_MessageHeader,
+ NULL),
+ GNUNET_MQ_handler_end ()
+ };
+ long l = (long) cls;
+ struct CadetTestChannelWrapper *ch;
+ enum GNUNET_CADET_ChannelOption flags;
+
+ reconnect_task = NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "reconnecting from line %ld\n",
+ l);
+ if (NULL != outgoing_ch)
+ {
+ GNUNET_CADET_channel_destroy (outgoing_ch);
+ outgoing_ch = NULL;
+ }
+ flags = GNUNET_CADET_OPTION_DEFAULT;
+ ch = GNUNET_new (struct CadetTestChannelWrapper);
+ outgoing_ch = GNUNET_CADET_channel_create (h1,
+ ch,
+ p_id[1],
+ &port,
+ flags,
+ NULL,
+ &disconnect_handler,
+ handlers);
+ ch->ch = outgoing_ch;
+ send_test_message (outgoing_ch);
+}
+
+/**
+ * Function called whenever an MQ-channel is destroyed, even if the destruction
+ * was requested by #GNUNET_CADET_channel_destroy.
+ * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
+ *
+ * It should clean up any associated state, including cancelling any pending
+ * transmission on this channel.
+ *
+ * @param cls Channel closure (channel wrapper).
+ * @param channel Connection to the other end (henceforth invalid).
+ */
+static void
+disconnect_handler (void *cls,
+ const struct GNUNET_CADET_Channel *channel)
+{
+ struct CadetTestChannelWrapper *ch_w = cls;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Channel disconnected at %d\n",
+ ok);
+ GNUNET_assert (ch_w->ch == channel);
+ if (channel == incoming_ch)
+ {
+ ok++;
+ incoming_ch = NULL;
+ }
+ else if (outgoing_ch == channel)
+ {
+ if (P2P_SIGNAL == test)
+ {
+ ok++;
+ }
+ outgoing_ch = NULL;
+ }
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Unknown channel! %p\n",
+ channel);
+ if (NULL != disconnect_task && REOPEN != test)
+ {
+ GNUNET_SCHEDULER_cancel (disconnect_task);
+ disconnect_task =
+ GNUNET_SCHEDULER_add_now (&gather_stats_and_exit,
+ (void *) __LINE__);
+ }
+ else if (NULL != reconnect_task && REOPEN == test)
+ {
+ GNUNET_SCHEDULER_cancel (reconnect_task);
+ reconnect_task =
+ GNUNET_SCHEDULER_add_now (&reconnect_op,
+ (void *) __LINE__);
+ }
+ GNUNET_free (ch_w);
+}
+
+
/**
* Abort test: schedule disconnect and shutdown immediately
*
{
payload = data_sent;
}
+ else if (REOPEN == test)
+ {
+ payload = data_sent;
+ data_sent++;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending DATA %u [%d bytes]\n",
+ data_sent, size);
+ }
else
{
GNUNET_assert (0);
(long) cls);
GNUNET_assert (0);
}
- if (NULL != disconnect_task)
+ if (NULL != disconnect_task && REOPEN != test)
{
GNUNET_SCHEDULER_cancel (disconnect_task);
disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
&gather_stats_and_exit,
(void *) __LINE__);
}
+ else if ((NULL != disconnect_task) && (REOPEN == test))
+ {
+ GNUNET_SCHEDULER_cancel (disconnect_task);
+ disconnect_task = GNUNET_SCHEDULER_add_delayed (
+ GNUNET_TIME_relative_multiply (short_time, 2),
+ &gather_stats_and_exit,
+ (void *) __LINE__);
+ }
+
+ if ((NULL != reconnect_task) && (REOPEN == test))
+ {
+ GNUNET_SCHEDULER_cancel (reconnect_task);
+ reconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
+ &reconnect_op,
+ (void *) __LINE__);
+ }
/* TODO: cannot return channel as-is, in order to unify the data handlers */
ch = GNUNET_new (struct CadetTestChannelWrapper);
}
-/**
- * Function called whenever an MQ-channel is destroyed, even if the destruction
- * was requested by #GNUNET_CADET_channel_destroy.
- * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
- *
- * It should clean up any associated state, including cancelling any pending
- * transmission on this channel.
- *
- * @param cls Channel closure (channel wrapper).
- * @param channel Connection to the other end (henceforth invalid).
- */
-static void
-disconnect_handler (void *cls,
- const struct GNUNET_CADET_Channel *channel)
-{
- struct CadetTestChannelWrapper *ch_w = cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Channel disconnected at %d\n",
- ok);
- GNUNET_assert (ch_w->ch == channel);
- if (channel == incoming_ch)
- {
- ok++;
- incoming_ch = NULL;
- }
- else if (outgoing_ch == channel)
- {
- if (P2P_SIGNAL == test)
- {
- ok++;
- }
- outgoing_ch = NULL;
- }
- else
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Unknown channel! %p\n",
- channel);
- if (NULL != disconnect_task)
- {
- GNUNET_SCHEDULER_cancel (disconnect_task);
- disconnect_task =
- GNUNET_SCHEDULER_add_now (&gather_stats_and_exit,
- (void *) __LINE__);
- }
- GNUNET_free (ch_w);
-}
-
-
/**
* START THE TESTCASE ITSELF, AS WE ARE CONNECTED TO THE CADET SERVICES.
*
enum GNUNET_CADET_ChannelOption flags;
test_task = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "start_test\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "start_test: %s\n", test_name);
if (NULL != disconnect_task)
{
GNUNET_SCHEDULER_cancel (disconnect_task);
if (KEEPALIVE == test)
return; /* Don't send any data. */
-
data_received = 0;
data_sent = 0;
ack_received = 0;
"Sending data initializer on channel %p...\n",
outgoing_ch);
send_test_message (outgoing_ch);
+ if (REOPEN == test)
+ {
+ reconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
+ &reconnect_op,
+ (void *) __LINE__);
+ GNUNET_SCHEDULER_cancel (disconnect_task);
+ disconnect_task = GNUNET_SCHEDULER_add_delayed (
+ GNUNET_TIME_relative_multiply (short_time, 2),
+ &gather_stats_and_exit,
+ (void *) __LINE__);
+ }
+
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "5 PEER LINE\n");
peers_requested = 5;
}
+ else if (strstr (argv[0], "_6_") != NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "6 PEER LINE\n");
+ peers_requested = 6;
+ }
else
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "SIZE UNKNOWN, USING 2\n");
*/
ok_goal = 2;
}
+ else if (strstr (argv[0], "_reopen") != NULL)
+ {
+ test = REOPEN;
+ test_name = "reopen";
+ ///* Test is supposed to generate the following callbacks:
+ // * 1 incoming channel (@dest)
+ // * [wait]
+ // * 1 received channel destroy (@dest)
+ // */
+ ok_goal = 7;
+ }
else
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "UNKNOWN\n");