/*
This file is part of GNUnet.
- Copyright (C) 2012 GNUnet e.V.
+ Copyright (C) 2012, 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
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
+ GNUnet is free software: you can redistribute it and/or modify it
+ 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.
GNUnet is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
+ 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/cadet_test_lib.c
#include "cadet_test_lib.h"
#include "gnunet_cadet_service.h"
+
/**
* Test context for a CADET Test.
*/
/**
* Array of handles to the CADET for each peer.
*/
- struct GNUNET_CADET_Handle **cadetes;
+ struct GNUNET_CADET_Handle **cadets;
/**
* Operation associated with the connection to the CADET.
*/
struct GNUNET_TESTBED_Operation **ops;
+ /**
+ * Number of peers running, size of the arrays above.
+ */
+ unsigned int num_peers;
+
/**
* Main function of the test to run once all CADETs are available.
*/
void *app_main_cls;
/**
- * Number of peers running, size of the arrays above.
+ * Handler for incoming tunnels.
*/
- unsigned int num_peers;
+ GNUNET_CADET_ConnectEventHandler connects;
/**
- * Handler for incoming tunnels.
+ * Function called when the transmit window size changes.
*/
- GNUNET_CADET_InboundChannelNotificationHandler *new_channel;
+ GNUNET_CADET_WindowSizeEventHandler window_changes;
/**
* Cleaner for destroyed incoming tunnels.
*/
- GNUNET_CADET_ChannelEndHandler *cleaner;
+ GNUNET_CADET_DisconnectEventHandler disconnects;
/**
* Message handlers.
*/
- struct GNUNET_CADET_MessageHandler* handlers;
+ struct GNUNET_MQ_MessageHandler *handlers;
/**
* Application ports.
*/
- const uint32_t *ports;
+ const struct GNUNET_HashCode **ports;
+
+ /**
+ * Number of ports in #ports.
+ */
+ unsigned int port_count;
};
*/
unsigned int peer;
+ /**
+ * Port handlers for open ports.
+ */
+ struct GNUNET_CADET_Port **ports;
+
/**
* General context.
*/
*/
static void *
cadet_connect_adapter (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
{
struct GNUNET_CADET_TEST_AdapterContext *actx = cls;
struct GNUNET_CADET_TEST_Context *ctx = actx->ctx;
struct GNUNET_CADET_Handle *h;
- h = GNUNET_CADET_connect (cfg,
- (void *) (long) actx->peer,
- ctx->cleaner,
- ctx->handlers);
+ h = GNUNET_CADET_connect (cfg);
+ if (NULL == h)
+ {
+ GNUNET_break(0);
+ return NULL;
+ }
+ if (NULL == ctx->ports)
+ return h;
+ actx->ports = GNUNET_new_array (ctx->port_count,
+ struct GNUNET_CADET_Port *);
+ for (unsigned int i = 0; i < ctx->port_count; i++)
+ {
+ actx->ports[i] = GNUNET_CADET_open_port (h,
+ ctx->ports[i],
+ ctx->connects,
+ (void *) (long) actx->peer,
+ ctx->window_changes,
+ ctx->disconnects,
+ ctx->handlers);
+ }
return h;
}
*/
static void
cadet_disconnect_adapter (void *cls,
- void *op_result)
+ void *op_result)
{
struct GNUNET_CADET_Handle *cadet = op_result;
struct GNUNET_CADET_TEST_AdapterContext *actx = cls;
+ if (NULL != actx->ports)
+ {
+ for (unsigned int i = 0; i < actx->ctx->port_count; i++)
+ {
+ GNUNET_CADET_close_port (actx->ports[i]);
+ actx->ports[i] = NULL;
+ }
+ GNUNET_free (actx->ports);
+ }
GNUNET_free (actx);
GNUNET_CADET_disconnect (cadet);
}
const char *emsg)
{
struct GNUNET_CADET_TEST_Context *ctx = cls;
- unsigned int i;
if (NULL != emsg)
{
- fprintf (stderr, "Failed to connect to CADET service: %s\n",
+ fprintf (stderr,
+ "Failed to connect to CADET service: %s\n",
emsg);
GNUNET_SCHEDULER_shutdown ();
return;
}
- for (i = 0; i < ctx->num_peers; i++)
+ for (unsigned int i = 0; i < ctx->num_peers; i++)
if (op == ctx->ops[i])
{
- ctx->cadetes[i] = ca_result;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "...cadet %u connected\n", i);
+ ctx->cadets[i] = ca_result;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "...cadet %u connected\n",
+ i);
}
- for (i = 0; i < ctx->num_peers; i++)
- if (NULL == ctx->cadetes[i])
+ for (unsigned int i = 0; i < ctx->num_peers; i++)
+ if (NULL == ctx->cadets[i])
return; /* still some CADET connections missing */
/* all CADET connections ready! */
ctx->app_main (ctx->app_main_cls,
ctx,
ctx->num_peers,
ctx->peers,
- ctx->cadetes);
+ ctx->cadets);
}
void
GNUNET_CADET_TEST_cleanup (struct GNUNET_CADET_TEST_Context *ctx)
{
- unsigned int i;
-
- for (i = 0; i < ctx->num_peers; i++)
+ for (unsigned int i = 0; i < ctx->num_peers; i++)
{
GNUNET_assert (NULL != ctx->ops[i]);
GNUNET_TESTBED_operation_done (ctx->ops[i]);
ctx->ops[i] = NULL;
}
GNUNET_free (ctx->ops);
- GNUNET_free (ctx->cadetes);
+ GNUNET_free (ctx->cadets);
+ GNUNET_free (ctx->handlers);
GNUNET_free (ctx);
GNUNET_SCHEDULER_shutdown ();
}
unsigned int links_failed)
{
struct GNUNET_CADET_TEST_Context *ctx = cls;
- unsigned int i;
+ if (0 != links_failed)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Some links failed (%u), ending\n",
+ links_failed);
+ exit (77);
+ }
if (num_peers != ctx->num_peers)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peers started %u/%u, ending\n",
- num_peers, ctx->num_peers);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Peers started %u/%u, ending\n",
+ num_peers,
+ ctx->num_peers);
exit (1);
}
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Testbed up, %u peers and %u links\n",
+ num_peers,
+ links_succeeded);
ctx->peers = peers;
- for (i = 0; i < num_peers; i++)
+ for (unsigned int i = 0; i < num_peers; i++)
{
struct GNUNET_CADET_TEST_AdapterContext *newctx;
+
newctx = GNUNET_new (struct GNUNET_CADET_TEST_AdapterContext);
newctx->peer = i;
newctx->ctx = ctx;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting to cadet %u\n", i);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Connecting to cadet %u\n",
+ i);
ctx->ops[i] = GNUNET_TESTBED_service_connect (ctx,
peers[i],
"cadet",
&cadet_connect_adapter,
&cadet_disconnect_adapter,
newctx);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "op handle %p\n", ctx->ops[i]);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "op handle %p\n",
+ ctx->ops[i]);
}
}
+/**
+ * Run a test using the given name, configuration file and number of peers.
+ * All cadet callbacks will receive the peer number (long) as the closure.
+ *
+ * @param testname Name of the test (for logging).
+ * @param cfgfile Name of the configuration file.
+ * @param num_peers Number of peers to start.
+ * @param tmain Main function to run once the testbed is ready.
+ * @param tmain_cls Closure for @a tmain.
+ * @param connects Handler for incoming channels.
+ * @param window_changes Handler for the window size change notification.
+ * @param disconnects Cleaner for destroyed incoming channels.
+ * @param handlers Message handlers.
+ * @param ports Ports the peers offer, NULL-terminated.
+ */
void
-GNUNET_CADET_TEST_run (const char *testname,
- const char *cfgname,
- unsigned int num_peers,
- GNUNET_CADET_TEST_AppMain tmain,
- void *tmain_cls,
- GNUNET_CADET_InboundChannelNotificationHandler new_channel,
- GNUNET_CADET_ChannelEndHandler cleaner,
- struct GNUNET_CADET_MessageHandler* handlers,
- const uint32_t *ports)
+GNUNET_CADET_TEST_ruN (const char *testname,
+ const char *cfgfile,
+ unsigned int num_peers,
+ GNUNET_CADET_TEST_AppMain tmain,
+ void *tmain_cls,
+ GNUNET_CADET_ConnectEventHandler connects,
+ GNUNET_CADET_WindowSizeEventHandler window_changes,
+ GNUNET_CADET_DisconnectEventHandler disconnects,
+ struct GNUNET_MQ_MessageHandler *handlers,
+ const struct GNUNET_HashCode **ports)
{
struct GNUNET_CADET_TEST_Context *ctx;
ctx = GNUNET_new (struct GNUNET_CADET_TEST_Context);
ctx->num_peers = num_peers;
- ctx->ops = GNUNET_malloc (num_peers * sizeof (struct GNUNET_TESTBED_Operation *));
- ctx->cadetes = GNUNET_malloc (num_peers * sizeof (struct GNUNET_CADET_Handle *));
+ ctx->ops = GNUNET_new_array (num_peers,
+ struct GNUNET_TESTBED_Operation *);
+ ctx->cadets = GNUNET_new_array (num_peers,
+ struct GNUNET_CADET_Handle *);
ctx->app_main = tmain;
ctx->app_main_cls = tmain_cls;
- ctx->new_channel = new_channel;
- ctx->cleaner = cleaner;
- ctx->handlers = handlers;
+ ctx->connects = connects;
+ ctx->window_changes = window_changes;
+ ctx->disconnects = disconnects;
+ ctx->handlers = GNUNET_MQ_copy_handlers (handlers);
ctx->ports = ports;
+ ctx->port_count = 0;
+ while (NULL != ctx->ports[ctx->port_count])
+ ctx->port_count++;
GNUNET_TESTBED_test_run (testname,
- cfgname,
+ cfgfile,
num_peers,
0LL, NULL, NULL,
- &cadet_test_run, ctx);
+ &cadet_test_run,
+ ctx);
}
/* end of cadet_test_lib.c */