From 71c68d0bbdb546bfe84b4536b447899c53cb3812 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 24 Jun 2016 14:05:58 +0000 Subject: move testbed logger to its own directory --- configure.ac | 2 + po/POTFILES.in | 7 +- src/Makefile.am | 2 +- src/nse/Makefile.am | 4 +- src/testbed-logger/Makefile.am | 57 +++ src/testbed-logger/gnunet-service-testbed-logger.c | 270 ++++++++++++ src/testbed-logger/test_testbed_logger_api.c | 272 ++++++++++++ src/testbed-logger/test_testbed_logger_api.conf | 6 + src/testbed-logger/testbed-logger.conf.in | 127 ++++++ src/testbed-logger/testbed_logger_api.c | 490 +++++++++++++++++++++ src/testbed/Makefile.am | 28 +- src/testbed/gnunet-service-testbed-logger.c | 270 ------------ src/testbed/test_testbed_logger_api.c | 272 ------------ src/testbed/test_testbed_logger_api.conf | 6 - src/testbed/testbed.conf.in | 11 - src/testbed/testbed_logger_api.c | 490 --------------------- 16 files changed, 1231 insertions(+), 1083 deletions(-) create mode 100644 src/testbed-logger/Makefile.am create mode 100644 src/testbed-logger/gnunet-service-testbed-logger.c create mode 100644 src/testbed-logger/test_testbed_logger_api.c create mode 100644 src/testbed-logger/test_testbed_logger_api.conf create mode 100644 src/testbed-logger/testbed-logger.conf.in create mode 100644 src/testbed-logger/testbed_logger_api.c delete mode 100644 src/testbed/gnunet-service-testbed-logger.c delete mode 100644 src/testbed/test_testbed_logger_api.c delete mode 100644 src/testbed/test_testbed_logger_api.conf delete mode 100644 src/testbed/testbed_logger_api.c diff --git a/configure.ac b/configure.ac index 11e9cbf3c..e4d3fa6a1 100644 --- a/configure.ac +++ b/configure.ac @@ -1601,6 +1601,8 @@ src/statistics/statistics.conf src/template/Makefile src/testbed/Makefile src/testbed/testbed.conf +src/testbed-logger/Makefile +src/testbed-logger/testbed-logger.conf src/testing/Makefile src/topology/Makefile src/transport/Makefile diff --git a/po/POTFILES.in b/po/POTFILES.in index e854ef48a..97732d8b4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -289,7 +289,8 @@ src/regex/gnunet-regex-simulation-profiler.c src/regex/gnunet-service-regex.c src/regex/perf-regex.c src/regex/plugin_block_regex.c -src/regex/regex_api.c +src/regex/regex_api_announce.c +src/regex/regex_api_search.c src/regex/regex_block_lib.c src/regex/regex_internal.c src/regex/regex_internal_dht.c @@ -350,12 +351,13 @@ src/testbed/gnunet-service-testbed_cache.c src/testbed/gnunet-service-testbed_connectionpool.c src/testbed/gnunet-service-testbed_cpustatus.c src/testbed/gnunet-service-testbed_links.c -src/testbed/gnunet-service-testbed-logger.c src/testbed/gnunet-service-testbed_meminfo.c src/testbed/gnunet-service-testbed_oc.c src/testbed/gnunet-service-testbed_peers.c src/testbed/gnunet_testbed_mpi_spawn.c src/testbed/gnunet-testbed-profiler.c +src/testbed-logger/gnunet-service-testbed-logger.c +src/testbed-logger/testbed_logger_api.c src/testbed/testbed_api_barriers.c src/testbed/testbed_api.c src/testbed/testbed_api_hosts.c @@ -368,7 +370,6 @@ src/testbed/testbed_api_testbed.c src/testbed/testbed_api_test.c src/testbed/testbed_api_topology.c src/testbed/testbed_api_underlay.c -src/testbed/testbed_logger_api.c src/testing/gnunet-testing.c src/testing/list-keys.c src/testing/testing.c diff --git a/src/Makefile.am b/src/Makefile.am index 24c2f583a..0ce2ac4de 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ if HAVE_TESTING TESTING = testing - TESTBED = testbed + TESTBED = testbed-logger testbed CONSENSUS = consensus SECRETSHARING = secretsharing endif diff --git a/src/nse/Makefile.am b/src/nse/Makefile.am index ebff9d251..9a163b160 100644 --- a/src/nse/Makefile.am +++ b/src/nse/Makefile.am @@ -66,7 +66,7 @@ gnunet_service_nse_LDADD = \ $(GN_LIBINTL) if ENABLE_NSE_HISTOGRAM gnunet_service_nse_LDADD += \ - $(top_builddir)/src/testbed/libgnunettestbedlogger.la + $(top_builddir)/src/testbed-logger/libgnunettestbedlogger.la endif @@ -111,5 +111,3 @@ perf_kdf_LDADD = \ EXTRA_DIST = \ test_nse.conf \ nse_profiler_test.conf - - diff --git a/src/testbed-logger/Makefile.am b/src/testbed-logger/Makefile.am new file mode 100644 index 000000000..7f372fd02 --- /dev/null +++ b/src/testbed-logger/Makefile.am @@ -0,0 +1,57 @@ +# This Makefile.am is in the public domain +AM_CPPFLAGS = -I$(top_srcdir)/src/include + +if MINGW + WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols +endif + +if USE_COVERAGE + AM_CFLAGS = --coverage -O0 + XLIB = -lgcov +endif + +libexecdir= $(pkglibdir)/libexec/ + +pkgcfgdir= $(pkgdatadir)/config.d/ + +pkgcfg_DATA = \ + testbed-logger.conf + +libexec_PROGRAMS = \ + gnunet-service-testbed-logger + +gnunet_service_testbed_logger_SOURCES = \ + gnunet-service-testbed-logger.c +gnunet_service_testbed_logger_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la + +lib_LTLIBRARIES = \ + libgnunettestbedlogger.la + +libgnunettestbedlogger_la_SOURCES = \ + testbed_logger_api.c +libgnunettestbedlogger_la_LIBADD = $(XLIB) \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) +libgnunettestbedlogger_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) \ + -version-info 0:0:0 + +check_PROGRAMS = \ + test_testbed_logger_api + +if ENABLE_TEST_RUN + AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; + TESTS = \ + test_testbed_logger_api +endif + +test_testbed_logger_api_SOURCES = \ + test_testbed_logger_api.c +test_testbed_logger_api_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ + libgnunettestbedlogger.la + +EXTRA_DIST = \ + test_testbed_logger_api.conf diff --git a/src/testbed-logger/gnunet-service-testbed-logger.c b/src/testbed-logger/gnunet-service-testbed-logger.c new file mode 100644 index 000000000..1c250b306 --- /dev/null +++ b/src/testbed-logger/gnunet-service-testbed-logger.c @@ -0,0 +1,270 @@ +/* + This file is part of GNUnet. + Copyright (C) 2008--2013 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 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. + + 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. +*/ + +/** + * @file testbed-logger/gnunet-service-testbed-logger.c + * @brief service for collecting messages and writing to a file + * @author Sree Harsha Totakura + */ + +#include "platform.h" +#include "gnunet_util_lib.h" + +/** + * Generic logging shorthand + */ +#define LOG(type, ...) \ + GNUNET_log (type, __VA_ARGS__) + +/** + * Debug logging shorthand + */ +#define LOG_DEBUG(...) \ + LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) + +/** + * The message queue for sending messages to clients + */ +struct MessageQueue +{ + /** + * The message to be sent + */ + struct GNUNET_MessageHeader *msg; + + /** + * The client to send the message to + */ + struct GNUNET_SERVER_Client *client; + + /** + * next pointer for DLL + */ + struct MessageQueue *next; + + /** + * prev pointer for DLL + */ + struct MessageQueue *prev; +}; + +/** + * The message queue head + */ +static struct MessageQueue *mq_head; + +/** + * The message queue tail + */ +static struct MessageQueue *mq_tail; + +/** + * Handle for buffered writing. + */ +struct GNUNET_BIO_WriteHandle *bio; + +/** + * The number of connections we have + */ +static unsigned int nconn; + +/** + * Are we shutting down? + */ +static int in_shutdown; + + +/** + * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST messages + * + * @param cls NULL + * @param client identification of the client + * @param msg the actual message + */ +static void +handle_log_msg (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *msg) +{ + uint16_t ms; + + ms = ntohs (msg->size); + ms -= sizeof (struct GNUNET_MessageHeader); + GNUNET_BIO_write (bio, &msg[1], ms); + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} + + +/** + * Task to clean up and shutdown nicely + * + * @param cls NULL + */ +static void +shutdown_task (void *cls) +{ + struct MessageQueue *mq_entry; + + in_shutdown = GNUNET_YES; + if (0 != nconn) + { + /* Delay shutdown if there are active connections */ + GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); + return; + } + while (NULL != (mq_entry = mq_head)) + { + GNUNET_free (mq_entry->msg); + GNUNET_SERVER_client_drop (mq_entry->client); + GNUNET_CONTAINER_DLL_remove (mq_head, + mq_tail, + mq_entry); + GNUNET_free (mq_entry); + } + GNUNET_break (GNUNET_OK == GNUNET_BIO_write_close (bio)); +} + + +/** +x * Functions with this signature are called whenever a client + * is disconnected on the network level. + * + * @param cls closure + * @param client identification of the client; NULL + * for the last call when the server is destroyed + */ +static void +client_disconnected (void *cls, + struct GNUNET_SERVER_Client *client) +{ + if (NULL == client) + { + GNUNET_break (0 == nconn); + return; + } + nconn--; + if (GNUNET_YES == in_shutdown) + GNUNET_SCHEDULER_shutdown (); +} + + +/** + * Functions with this signature are called whenever a client + * is connected on the network level. + * + * @param cls closure + * @param client identification of the client + */ +static void +client_connected (void *cls, + struct GNUNET_SERVER_Client *client) +{ + if (NULL == client) + { + GNUNET_break (0 == nconn); + return; + } + GNUNET_SERVER_client_persist_ (client); + nconn++; +} + + +/** + * Testbed setup + * + * @param cls closure + * @param server the initialized server + * @param cfg configuration to use + */ +static void +logger_run (void *cls, + struct GNUNET_SERVER_Handle *server, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + static const struct GNUNET_SERVER_MessageHandler message_handlers[] = { + {&handle_log_msg, NULL, GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG, 0}, + {NULL, NULL, 0, 0} + }; + char *dir; + char *fn; + char *hname; + size_t hname_len; + pid_t pid; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (cfg, + "TESTBED-LOGGER", + "DIR", + &dir)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "TESTBED-LOGGER", + "DIR"); + GNUNET_SCHEDULER_shutdown (); + return; + } + pid = getpid (); + hname_len = GNUNET_OS_get_hostname_max_length (); + hname = GNUNET_malloc (hname_len); + if (0 != gethostname (hname, hname_len)) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + "Cannot get hostname. Exiting\n"); + GNUNET_free (hname); + GNUNET_free (dir); + GNUNET_SCHEDULER_shutdown (); + return; + } + GNUNET_asprintf (&fn, + "%s/%.*s_%jd.dat", + dir, + hname_len, + hname, + (intmax_t) pid); + GNUNET_free (hname); + GNUNET_free (dir); + if (NULL == (bio = GNUNET_BIO_write_open (fn))) + { + GNUNET_free (fn); + GNUNET_SCHEDULER_shutdown (); + return; + } + GNUNET_free (fn); + GNUNET_SERVER_add_handlers (server, message_handlers); + GNUNET_SERVER_connect_notify (server, &client_connected, NULL); + GNUNET_SERVER_disconnect_notify (server, &client_disconnected, NULL); + GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); + LOG_DEBUG ("TESTBED-LOGGER startup complete\n"); +} + + +/** + * The starting point of execution + */ +int +main (int argc, char *const *argv) +{ + return (GNUNET_OK == + GNUNET_SERVICE_run (argc, argv, "testbed-logger", + GNUNET_SERVICE_OPTION_NONE, + &logger_run, NULL)) ? 0 : 1; +} + +/* end of gnunet-service-testbed-logger.c */ diff --git a/src/testbed-logger/test_testbed_logger_api.c b/src/testbed-logger/test_testbed_logger_api.c new file mode 100644 index 000000000..8f7391f22 --- /dev/null +++ b/src/testbed-logger/test_testbed_logger_api.c @@ -0,0 +1,272 @@ +/* + This file is part of GNUnet + Copyright (C) 2008--2013 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 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. + + 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. + */ +/** + * @file testbed-logger/test_testbed_logger_api.c + * @brief testcases for the testbed logger api + * @author Sree Harsha Totakura + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_testing_lib.h" +#include "gnunet_testbed_logger_service.h" + +/** + * Generic logging shortcut + */ +#define LOG(kind,...) \ + GNUNET_log (kind, __VA_ARGS__) + +/** + * Relative time seconds shorthand + */ +#define TIME_REL_SECS(sec) \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec) + +/** + * Opaque handle for the logging service + */ +static struct GNUNET_TESTBED_LOGGER_Handle *h; + +static struct GNUNET_TESTING_Peer *peer; + +static char *search_dir; + +/** + * Abort task identifier + */ +static struct GNUNET_SCHEDULER_Task *abort_task; +static struct GNUNET_SCHEDULER_Task *write_task; + +static int result; + +#define CANCEL_TASK(task) do { \ + if (NULL != task) \ + { \ + GNUNET_SCHEDULER_cancel (task); \ + task = NULL; \ + } \ + } while (0) + +/** + * shortcut to exit during failure + */ +#define FAIL_TEST(cond, ret) do { \ + if (!(cond)) { \ + GNUNET_break(0); \ + CANCEL_TASK (abort_task); \ + abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL); \ + ret; \ + } \ + } while (0) + + +/** + * Shutdown nicely + * + * @param cls NULL + * @param tc the task context + */ +static void +shutdown_now () +{ + CANCEL_TASK (abort_task); + CANCEL_TASK (write_task); + GNUNET_free_non_null (search_dir); + if (NULL != h) + GNUNET_TESTBED_LOGGER_disconnect (h); + GNUNET_SCHEDULER_shutdown (); +} + + +static void +do_abort (void *cls) +{ + LOG (GNUNET_ERROR_TYPE_WARNING, + "Aborting\n"); + abort_task = NULL; + shutdown_now (); +} + + +#define BSIZE 1024 + + +/** + * Function called to iterate over a directory. + * + * @param cls closure + * @param filename complete filename (absolute path) + * @return #GNUNET_OK to continue to iterate, + * #GNUNET_NO to stop iteration with no error, + * #GNUNET_SYSERR to abort iteration with error! + */ +static int +iterator_cb (void *cls, + const char *filename) +{ + const char *fn; + size_t len; + uint64_t fs; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Iterator sees file %s\n", + filename); + len = strlen (filename); + fn = filename + len; + if (0 != strcasecmp (".dat", fn - 4)) + return GNUNET_OK; + if (GNUNET_OK != + GNUNET_DISK_file_size (filename, + &fs, + GNUNET_NO, + GNUNET_YES)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Failed to obtain file size for file %s\n", + filename); + return GNUNET_SYSERR; + } + if ((BSIZE * 2) != fs) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Unexpected file size for file %s\n", + filename); + /* The file size should be equal to what we + have written */ + return GNUNET_SYSERR; + } + result = GNUNET_OK; + return GNUNET_OK; +} + + +/** + * Functions of this type are called to notify a successful + * transmission of the message to the logger service + * + * @param cls the closure given to GNUNET_TESTBED_LOGGER_send() + * @param size the amount of data sent + */ +static void +flush_comp (void *cls, + size_t size) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Flush running\n"); + FAIL_TEST (&write_task == cls, + return); + FAIL_TEST ((BSIZE * 2) == size, + return); + FAIL_TEST (GNUNET_OK == + GNUNET_TESTING_peer_stop (peer), + return); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Peer stopped, scanning %s\n", + search_dir); + FAIL_TEST (GNUNET_SYSERR != + GNUNET_DISK_directory_scan (search_dir, + &iterator_cb, + NULL), + return); + shutdown_now (); +} + + +static void +do_write (void *cls) +{ + static int i; + char buf[BSIZE]; + + write_task = NULL; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Write task running\n"); + if (0 == i) + write_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS(1), + &do_write, + NULL); + (void) memset (buf, i, BSIZE); + GNUNET_TESTBED_LOGGER_write (h, + buf, + BSIZE); + if (0 == i++) + return; + GNUNET_TESTBED_LOGGER_flush (h, + GNUNET_TIME_UNIT_FOREVER_REL, + &flush_comp, + &write_task); +} + + +/** + * Signature of the 'main' function for a (single-peer) testcase that + * is run using #GNUNET_TESTING_peer_run(). + * + * @param cls closure + * @param cfg configuration of the peer that was started + * @param peer identity of the peer that was created + */ +static void +test_main (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *p) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Connecting to logger\n"); + FAIL_TEST (NULL != (h = GNUNET_TESTBED_LOGGER_connect (cfg)), + return); + FAIL_TEST (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, + "testbed-logger", + "dir", + &search_dir), + return); + peer = p; + write_task = GNUNET_SCHEDULER_add_now (&do_write, + NULL); + abort_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (10), + &do_abort, + NULL); +} + + +/** + * Main function + */ +int +main (int argc, char **argv) +{ + int ret; + + result = GNUNET_SYSERR; + GNUNET_log_setup ("test-testbed-logger-api", + "WARNING", + NULL); + ret = GNUNET_TESTING_service_run ("test-testbed-logger", + "testbed-logger", + "test_testbed_logger_api.conf", + &test_main, + NULL); + if (0 != ret) + return 1; + if (GNUNET_OK != result) + return 2; + return 0; +} diff --git a/src/testbed-logger/test_testbed_logger_api.conf b/src/testbed-logger/test_testbed_logger_api.conf new file mode 100644 index 000000000..57ce5c254 --- /dev/null +++ b/src/testbed-logger/test_testbed_logger_api.conf @@ -0,0 +1,6 @@ +[testbed-logger] +UNIXPATH=/tmp/testbed-logger.sock +DIR=$GNUNET_TEST_HOME/data + +[PATHS] +GNUNET_TEST_HOME = /tmp/test-testbed/ \ No newline at end of file diff --git a/src/testbed-logger/testbed-logger.conf.in b/src/testbed-logger/testbed-logger.conf.in new file mode 100644 index 000000000..094328c7b --- /dev/null +++ b/src/testbed-logger/testbed-logger.conf.in @@ -0,0 +1,127 @@ +[testbed] +AUTOSTART = NO +@JAVAPORT@ PORT = 2101 +HOSTNAME = localhost +BINARY = gnunet-service-testbed + +# How long should operations wait? +OPERATION_TIMEOUT = 30 s + +# Set this to the path where the testbed helper is installed. By default the +# helper binary is searched in @prefix@/lib/gnunet/libexec/ +# HELPER_BINARY_PATH = @prefix@/lib/gnunet/libexec/gnunet-helper-testbed + +# Add your local network address here. For example, if you want to run +# testbed on a group of hosts connected to network 192.168.1.0/24, then set +# ACCEPT_FROM = 127.0.0.1; 192.168.1.0/24; +# Multiple network addresses can be given. They should be separated by `;' +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; + +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-testbed.sock +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + +# How many maximum number of operations can be run in parallel. This number +# should be decreased if the system is getting overloaded and to reduce the load +# exerted by the emulation. +MAX_PARALLEL_OPERATIONS = 1000 +MAX_PARALLEL_TOPOLOGY_CONFIG_OPERATIONS = 1 + +# What topology should be generated by the helper functions GNUNET_TESTBED_run() +# and GNUNET_TESTBED_test_run(). This option has no effect if testbed is +# initialized with other functions. Valid values can be found at: +# https://gnunet.org/supported-topologies +OVERLAY_TOPOLOGY = NONE + +# Number of random links to be included to the generate the above topology. +# Note that not all topologies require this option and ignore it. Topologies +# requiring this option are RANDOM, SMALL_WORLD and SMALL_WORLD ring. +# OVERLAY_RANDOM_LINKS = + +# This option is required if the OVERLAY_TOPOLOGY is set to FROM_FILE. It is +# ignored for all other topologies. This option should contain the path to +# the file containing the topology information. The format of the file is +# presented at: https://gnunet.org/topology-file-format +# OVERLAY_TOPOLOGY_FILE = /path/to/topology-file + +# The following options are required if the OVERLAY_TOPOLOGY is set to +# SCALE_FREE. They are ignored in all other cases. +# The number of maximum peers which can connect to a peer +SCALE_FREE_TOPOLOGY_CAP = 70 +# The minimum number of peers which a peer has to connect +SCALE_FREE_TOPOLOGY_M = 5 + +# How many maximum number of handles to peers' services should be kept open at +# any time. This number also keeps a check on the number of open descriptors as +# opening a service connection results in opening a file descriptor. +MAX_PARALLEL_SERVICE_CONNECTIONS = 256 + +# Size of the internal testbed cache. It is used to cache handles to peers +# while trying to connect them. +CACHE_SIZE = 30 + +# Maximum number of file descriptors a testbed controller is permitted to keep +# open. +MAX_OPEN_FDS = 512 + +# How long should we wait for testbed to setup while using helper functions +# GNUNET_TESTBED_test_run() and GNUNET_TESTBED_run() +SETUP_TIMEOUT = 5 m + +# Where should testbed write load statistics data +# STATS_DIR = /tmp/load + +# What services should be shared among peers. +# Format is "[] [] ...". The shared services are +# started standalone without any other peer services or a hostkey. For this +# reason, only services which doesn't depend on other services can only be +# shared. Example: To share peerinfo among every 10 peers. The following spec +# will start 5 peerinfo services when 50 peers are started: +# +# SHARED_SERVICES = peerinfo:10 +# +# To share multiple services +# +# SHARED_SERVICES = service1:n_share1 service2:n_share2 ... +# +# Default is to share no services +SHARED_SERVICES = + + +[testbed-logger] +AUTOSTART = NO +@UNIXONLY@ PORT = 2102 +HOSTNAME = localhost +BINARY = gnunet-service-testbed-logger +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-gnunet-testbed-logger.sock +DIR = /tmp +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + + +[testbed-barrier] +AUTOSTART = NO +@UNIXONLY@ PORT = 2103 +HOSTNAME = localhost +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-testbed-barrier.sock +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES + + +# This section is related to configuring underlay restrictions to simulate +# connectivity restrictions of NAT boxes +[testbed-underlay] +AUTOSTART = NO +NOARMBIND = YES +BINARY = gnunet-daemon-testbed-underlay +# The sqlite3 database file containing information about what underlay +# restrictions to apply +# DBFILE = + +[latency-logger] +AUTOSTART = NO +NOARMBIND = YES +BINARY = gnunet-daemon-latency-logger +# The sqlite3 database file where the latency values are to be stored +# DBFILE = \ No newline at end of file diff --git a/src/testbed-logger/testbed_logger_api.c b/src/testbed-logger/testbed_logger_api.c new file mode 100644 index 000000000..aaf18cd33 --- /dev/null +++ b/src/testbed-logger/testbed_logger_api.c @@ -0,0 +1,490 @@ +/* + This file is part of GNUnet + Copyright (C) 2008--2013 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 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. + + 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. + */ + +/** + * @file testbed-logger/testbed_logger_api.c + * @brief Client-side routines for communicating with the tesbted logger service + * @author Sree Harsha Totakura + */ + +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_testbed_logger_service.h" + +/** + * Generic logging shorthand + */ +#define LOG(kind, ...) \ + GNUNET_log_from (kind, "testbed-logger-api", __VA_ARGS__) + +/** + * Debug logging + */ +#define LOG_DEBUG(...) \ + LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) + +#ifdef GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD +#undef GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD +#endif + +/** + * Threshold after which exponential backoff should not increase (15 s). + */ +#define GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3) + +/** + * The size of the buffer we fill before sending out the message + */ +#define BUFFER_SIZE GNUNET_SERVER_MAX_MESSAGE_SIZE + +/** + * The message queue for sending messages to the controller service + */ +struct MessageQueue +{ + /** + * next pointer for DLL + */ + struct MessageQueue *next; + + /** + * prev pointer for DLL + */ + struct MessageQueue *prev; + + /** + * The message to be sent + */ + struct GNUNET_MessageHeader *msg; + + /** + * Completion callback + */ + GNUNET_TESTBED_LOGGER_FlushCompletion cb; + + /** + * callback closure + */ + void *cb_cls; +}; + + +/** + * Connection handle for the logger service + */ +struct GNUNET_TESTBED_LOGGER_Handle +{ + /** + * Client connection + */ + struct GNUNET_CLIENT_Connection *client; + + /** + * The transport handle + */ + struct GNUNET_CLIENT_TransmitHandle *th; + + /** + * DLL head for the message queue + */ + struct MessageQueue *mq_head; + + /** + * DLL tail for the message queue + */ + struct MessageQueue *mq_tail; + + /** + * Flush completion callback + */ + GNUNET_TESTBED_LOGGER_FlushCompletion cb; + + /** + * Closure for the above callback + */ + void *cb_cls; + + /** + * Local buffer for data to be transmitted + */ + void *buf; + + /** + * The size of the local buffer + */ + size_t bs; + + /** + * Number of bytes wrote since last flush + */ + size_t bwrote; + + /** + * How long after should we retry sending a message to the service? + */ + struct GNUNET_TIME_Relative retry_backoff; + + /** + * Task to call the flush completion callback + */ + struct GNUNET_SCHEDULER_Task * flush_completion_task; + + /** + * Task to be executed when flushing takes too long + */ + struct GNUNET_SCHEDULER_Task * timeout_flush_task; +}; + + +/** + * Cancels the flush timeout task + * + * @param h handle to the logger + */ +static void +cancel_timeout_flush (struct GNUNET_TESTBED_LOGGER_Handle *h) +{ + GNUNET_SCHEDULER_cancel (h->timeout_flush_task); + h->timeout_flush_task = NULL; +} + + +/** + * Task to call the flush completion notification + * + * @param cls the logger handle + */ +static void +call_flush_completion (void *cls) +{ + struct GNUNET_TESTBED_LOGGER_Handle *h = cls; + GNUNET_TESTBED_LOGGER_FlushCompletion cb; + void *cb_cls; + size_t bw; + + h->flush_completion_task = NULL; + bw = h->bwrote; + h->bwrote = 0; + cb = h->cb; + h->cb = NULL; + cb_cls = h->cb_cls; + h->cb_cls = NULL; + if (NULL != h->timeout_flush_task) + cancel_timeout_flush (h); + if (NULL != cb) + cb (cb_cls, bw); +} + + +/** + * Schedule the flush completion notification task + * + * @param h logger handle + */ +static void +trigger_flush_notification (struct GNUNET_TESTBED_LOGGER_Handle *h) +{ + if (NULL != h->flush_completion_task) + GNUNET_SCHEDULER_cancel (h->flush_completion_task); + h->flush_completion_task = GNUNET_SCHEDULER_add_now (&call_flush_completion, h); +} + + +/** + * Function called to notify a client about the connection begin ready to queue + * more data. "buf" will be NULL and "size" zero if the connection was closed + * for writing in the meantime. + * + * @param cls closure + * @param size number of bytes available in buf + * @param buf where the callee should write the message + * @return number of bytes written to buf + */ +static size_t +transmit_ready_notify (void *cls, size_t size, void *buf) +{ + struct GNUNET_TESTBED_LOGGER_Handle *h = cls; + struct MessageQueue *mq; + + h->th = NULL; + mq = h->mq_head; + GNUNET_assert (NULL != mq); + if ((0 == size) && (NULL == buf)) /* Timeout */ + { + LOG_DEBUG ("Message sending timed out -- retrying\n"); + h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); + h->th = + GNUNET_CLIENT_notify_transmit_ready (h->client, + ntohs (mq->msg->size), + h->retry_backoff, GNUNET_YES, + &transmit_ready_notify, h); + return 0; + } + h->retry_backoff = GNUNET_TIME_UNIT_ZERO; + GNUNET_assert (ntohs (mq->msg->size) <= size); + size = ntohs (mq->msg->size); + memcpy (buf, mq->msg, size); + LOG_DEBUG ("Message of type: %u and size: %u sent\n", + ntohs (mq->msg->type), size); + GNUNET_free (mq->msg); + GNUNET_CONTAINER_DLL_remove (h->mq_head, h->mq_tail, mq); + GNUNET_free (mq); + h->bwrote += (size - sizeof (struct GNUNET_MessageHeader)); + mq = h->mq_head; + if (NULL != mq) + { + h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); + h->th = + GNUNET_CLIENT_notify_transmit_ready (h->client, + ntohs (mq->msg->size), + h->retry_backoff, GNUNET_YES, + &transmit_ready_notify, h); + return size; + } + if (NULL != h->cb) + trigger_flush_notification (h); /* Call the flush completion callback */ + return size; +} + + +/** + * Queues a message in send queue of the logger handle + * + * @param h the logger handle + * @param msg the message to queue + */ +static void +queue_message (struct GNUNET_TESTBED_LOGGER_Handle *h, + struct GNUNET_MessageHeader *msg) +{ + struct MessageQueue *mq; + uint16_t type; + uint16_t size; + + type = ntohs (msg->type); + size = ntohs (msg->size); + mq = GNUNET_new (struct MessageQueue); + mq->msg = msg; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Queueing message of type %u, size %u for sending\n", type, + ntohs (msg->size)); + GNUNET_CONTAINER_DLL_insert_tail (h->mq_head, h->mq_tail, mq); + if (NULL == h->th) + { + h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); + h->th = + GNUNET_CLIENT_notify_transmit_ready (h->client, size, + h->retry_backoff, GNUNET_YES, + &transmit_ready_notify, + h); + } +} + + +/** + * Send the buffered data to the service + * + * @param h the logger handle + */ +static void +dispatch_buffer (struct GNUNET_TESTBED_LOGGER_Handle *h) +{ + struct GNUNET_MessageHeader *msg; + size_t msize; + + msize = sizeof (struct GNUNET_MessageHeader) + h->bs; + msg = GNUNET_realloc (h->buf, msize); + h->buf = NULL; + memmove (&msg[1], msg, h->bs); + h->bs = 0; + msg->type = htons (GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG); + msg->size = htons (msize); + queue_message (h, msg); +} + + +/** + * Connect to the testbed logger service + * + * @param cfg configuration to use + * @return the handle which can be used for sending data to the service; NULL + * upon any error + */ +struct GNUNET_TESTBED_LOGGER_Handle * +GNUNET_TESTBED_LOGGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_TESTBED_LOGGER_Handle *h; + struct GNUNET_CLIENT_Connection *client; + + client = GNUNET_CLIENT_connect ("testbed-logger", cfg); + if (NULL == client) + return NULL; + h = GNUNET_new (struct GNUNET_TESTBED_LOGGER_Handle); + h->client = client; + return h; +} + + +/** + * Disconnect from the logger service. + * + * @param h the logger handle + */ +void +GNUNET_TESTBED_LOGGER_disconnect (struct GNUNET_TESTBED_LOGGER_Handle *h) +{ + struct MessageQueue *mq; + unsigned int lost; + + if (NULL != h->flush_completion_task) + GNUNET_SCHEDULER_cancel (h->flush_completion_task); + lost = 0; + while (NULL != (mq = h->mq_head)) + { + GNUNET_CONTAINER_DLL_remove (h->mq_head, h->mq_tail, mq); + GNUNET_free (mq->msg); + GNUNET_free (mq); + lost++; + } + if (0 != lost) + LOG (GNUNET_ERROR_TYPE_WARNING, "Cleaning up %u unsent logger message[s]\n", + lost); + GNUNET_CLIENT_disconnect (h->client); + GNUNET_free (h); +} + + +/** + * Send data to be logged to the logger service. The data will be buffered and + * will be sent upon an explicit call to GNUNET_TESTBED_LOGGER_flush() or upon + * exceeding a threshold size. + * + * @param h the logger handle + * @param data the data to send; + * @param size how many bytes of data to send + */ +void +GNUNET_TESTBED_LOGGER_write (struct GNUNET_TESTBED_LOGGER_Handle *h, + const void *data, size_t size) +{ + size_t fit_size; + + GNUNET_assert (0 != size); + GNUNET_assert (NULL != data); + GNUNET_assert (size <= (BUFFER_SIZE - sizeof (struct GNUNET_MessageHeader))); + fit_size = sizeof (struct GNUNET_MessageHeader) + h->bs + size; + if ( BUFFER_SIZE < fit_size ) + dispatch_buffer (h); + if (NULL == h->buf) + { + h->buf = GNUNET_malloc (size); + h->bs = size; + memcpy (h->buf, data, size); + goto dispatch_ready; + } + h->buf = GNUNET_realloc (h->buf, h->bs + size); + memcpy (h->buf + h->bs, data, size); + h->bs += size; + + dispatch_ready: + if (BUFFER_SIZE == fit_size) + dispatch_buffer (h); +} + + +/** + * Task to be executed when flushing our local buffer takes longer than timeout + * given to GNUNET_TESTBED_LOGGER_flush(). The flush completion callback will + * be called with 0 as the amount of data sent. + * + * @param cls the logger handle + */ +static void +timeout_flush (void *cls) +{ + struct GNUNET_TESTBED_LOGGER_Handle *h = cls; + GNUNET_TESTBED_LOGGER_FlushCompletion cb; + void *cb_cls; + + h->timeout_flush_task = NULL; + cb = h->cb; + h->cb = NULL; + cb_cls = h->cb_cls; + h->cb_cls = NULL; + if (NULL != h->flush_completion_task) + { + GNUNET_SCHEDULER_cancel (h->flush_completion_task); + h->flush_completion_task = NULL; + } + if (NULL != cb) + cb (cb_cls, 0); +} + + +/** + * Flush the buffered data to the logger service + * + * @param h the logger handle + * @param timeout how long to wait before calling the flust completion callback + * @param cb the callback to call after the data is flushed + * @param cb_cls the closure for the above callback + */ +void +GNUNET_TESTBED_LOGGER_flush (struct GNUNET_TESTBED_LOGGER_Handle *h, + struct GNUNET_TIME_Relative timeout, + GNUNET_TESTBED_LOGGER_FlushCompletion cb, + void *cb_cls) +{ + h->cb = cb; + h->cb_cls = cb_cls; + GNUNET_assert (NULL == h->timeout_flush_task); + h->timeout_flush_task = + GNUNET_SCHEDULER_add_delayed (timeout, &timeout_flush, h); + if (NULL == h->buf) + { + trigger_flush_notification (h); + return; + } + dispatch_buffer (h); +} + + +/** + * Cancel notification upon flush. Should only be used when the flush + * completion callback given to GNUNET_TESTBED_LOGGER_flush() is not already + * called. + * + * @param h the logger handle + */ +void +GNUNET_TESTBED_LOGGER_flush_cancel (struct GNUNET_TESTBED_LOGGER_Handle *h) +{ + if (NULL != h->flush_completion_task) + { + GNUNET_SCHEDULER_cancel (h->flush_completion_task); + h->flush_completion_task = NULL; + } + if (NULL != h->timeout_flush_task) + cancel_timeout_flush (h); + h->cb = NULL; + h->cb_cls = NULL; +} + +/* End of testbed_logger_api.c */ diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am index 8b5d7457a..b5a7758f0 100644 --- a/src/testbed/Makefile.am +++ b/src/testbed/Makefile.am @@ -27,7 +27,6 @@ endif libexec_PROGRAMS = \ gnunet-service-testbed \ gnunet-helper-testbed \ - gnunet-service-testbed-logger \ gnunet-daemon-testbed-blacklist \ $(underlay_daemon) \ $(latency_logger) @@ -59,11 +58,6 @@ gnunet_service_testbed_LDADD = $(XLIB) \ $(top_builddir)/src/arm/libgnunetarm.la \ $(LTLIBINTL) $(Z_LIBS) -gnunet_service_testbed_logger_SOURCES = \ - gnunet-service-testbed-logger.c -gnunet_service_testbed_logger_LDADD = \ - $(top_builddir)/src/util/libgnunetutil.la - gnunet_testbed_profiler_SOURCES = \ gnunet-testbed-profiler.c gnunet_testbed_profiler_LDADD = $(XLIB) \ @@ -97,8 +91,7 @@ gnunet_daemon_latency_logger_LDADD = $(XLIB) \ $(LTLIBINTL) -lsqlite3 lib_LTLIBRARIES = \ - libgnunettestbed.la \ - libgnunettestbedlogger.la + libgnunettestbed.la libgnunettestbed_la_SOURCES = \ testbed_api.c testbed_api.h testbed.h \ @@ -125,15 +118,6 @@ libgnunettestbed_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ -version-info 0:0:0 -libgnunettestbedlogger_la_SOURCES = \ - testbed_logger_api.c -libgnunettestbedlogger_la_LIBADD = $(XLIB) \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(LTLIBINTL) -libgnunettestbedlogger_la_LDFLAGS = \ - $(GN_LIB_LDFLAGS) \ - -version-info 0:0:0 - generate_underlay_topology_SOURCES = generate-underlay-topology.c generate_underlay_topology_LDADD = $(XLIB) \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -142,7 +126,6 @@ generate_underlay_topology_LDADD = $(XLIB) \ check_PROGRAMS = \ test_testbed_api_hosts \ - test_testbed_logger_api \ test_gnunet_helper_testbed \ test_testbed_api_controllerlink \ test_testbed_api_2peers_1controller \ @@ -176,7 +159,6 @@ if ENABLE_TEST_RUN AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; TESTS = \ test_testbed_api \ - test_testbed_logger_api \ test_testbed_api_sd \ test_testbed_api_operations \ test_testbed_api_hosts \ @@ -219,13 +201,6 @@ test_testbed_api_LDADD = \ $(top_builddir)/src/arm/libgnunetarm.la \ libgnunettestbed.la -test_testbed_logger_api_SOURCES = \ - test_testbed_logger_api.c -test_testbed_logger_api_LDADD = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ - libgnunettestbedlogger.la - test_testbed_api_sd_SOURCES = \ test_testbed_api_sd.c test_testbed_api_sd_LDADD = \ @@ -398,7 +373,6 @@ EXTRA_DIST = \ test_testbed_api_statistics.conf \ test_testbed_api_test_timeout.conf \ test_testbed_api_template.conf \ - test_testbed_logger_api.conf \ test_testbed_api_testbed_run_topologyring.conf \ test_testbed_api_testbed_run_topologyclique.conf \ test_testbed_api_testbed_run_topologyline.conf \ diff --git a/src/testbed/gnunet-service-testbed-logger.c b/src/testbed/gnunet-service-testbed-logger.c deleted file mode 100644 index 0f9fab01b..000000000 --- a/src/testbed/gnunet-service-testbed-logger.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2008--2013 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 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. - - 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. -*/ - -/** - * @file testbed/gnunet-service-testbed-logger.c - * @brief service for collecting messages and writing to a file - * @author Sree Harsha Totakura - */ - -#include "platform.h" -#include "gnunet_util_lib.h" - -/** - * Generic logging shorthand - */ -#define LOG(type, ...) \ - GNUNET_log (type, __VA_ARGS__) - -/** - * Debug logging shorthand - */ -#define LOG_DEBUG(...) \ - LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) - -/** - * The message queue for sending messages to clients - */ -struct MessageQueue -{ - /** - * The message to be sent - */ - struct GNUNET_MessageHeader *msg; - - /** - * The client to send the message to - */ - struct GNUNET_SERVER_Client *client; - - /** - * next pointer for DLL - */ - struct MessageQueue *next; - - /** - * prev pointer for DLL - */ - struct MessageQueue *prev; -}; - -/** - * The message queue head - */ -static struct MessageQueue *mq_head; - -/** - * The message queue tail - */ -static struct MessageQueue *mq_tail; - -/** - * Handle for buffered writing. - */ -struct GNUNET_BIO_WriteHandle *bio; - -/** - * The number of connections we have - */ -static unsigned int nconn; - -/** - * Are we shutting down? - */ -static int in_shutdown; - - -/** - * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST messages - * - * @param cls NULL - * @param client identification of the client - * @param msg the actual message - */ -static void -handle_log_msg (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *msg) -{ - uint16_t ms; - - ms = ntohs (msg->size); - ms -= sizeof (struct GNUNET_MessageHeader); - GNUNET_BIO_write (bio, &msg[1], ms); - GNUNET_SERVER_receive_done (client, GNUNET_OK); -} - - -/** - * Task to clean up and shutdown nicely - * - * @param cls NULL - */ -static void -shutdown_task (void *cls) -{ - struct MessageQueue *mq_entry; - - in_shutdown = GNUNET_YES; - if (0 != nconn) - { - /* Delay shutdown if there are active connections */ - GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); - return; - } - while (NULL != (mq_entry = mq_head)) - { - GNUNET_free (mq_entry->msg); - GNUNET_SERVER_client_drop (mq_entry->client); - GNUNET_CONTAINER_DLL_remove (mq_head, - mq_tail, - mq_entry); - GNUNET_free (mq_entry); - } - GNUNET_break (GNUNET_OK == GNUNET_BIO_write_close (bio)); -} - - -/** -x * Functions with this signature are called whenever a client - * is disconnected on the network level. - * - * @param cls closure - * @param client identification of the client; NULL - * for the last call when the server is destroyed - */ -static void -client_disconnected (void *cls, - struct GNUNET_SERVER_Client *client) -{ - if (NULL == client) - { - GNUNET_break (0 == nconn); - return; - } - nconn--; - if (GNUNET_YES == in_shutdown) - GNUNET_SCHEDULER_shutdown (); -} - - -/** - * Functions with this signature are called whenever a client - * is connected on the network level. - * - * @param cls closure - * @param client identification of the client - */ -static void -client_connected (void *cls, - struct GNUNET_SERVER_Client *client) -{ - if (NULL == client) - { - GNUNET_break (0 == nconn); - return; - } - GNUNET_SERVER_client_persist_ (client); - nconn++; -} - - -/** - * Testbed setup - * - * @param cls closure - * @param server the initialized server - * @param cfg configuration to use - */ -static void -logger_run (void *cls, - struct GNUNET_SERVER_Handle *server, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - static const struct GNUNET_SERVER_MessageHandler message_handlers[] = { - {&handle_log_msg, NULL, GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG, 0}, - {NULL, NULL, 0, 0} - }; - char *dir; - char *fn; - char *hname; - size_t hname_len; - pid_t pid; - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (cfg, - "TESTBED-LOGGER", - "DIR", - &dir)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "TESTBED-LOGGER", - "DIR"); - GNUNET_SCHEDULER_shutdown (); - return; - } - pid = getpid (); - hname_len = GNUNET_OS_get_hostname_max_length (); - hname = GNUNET_malloc (hname_len); - if (0 != gethostname (hname, hname_len)) - { - LOG (GNUNET_ERROR_TYPE_ERROR, - "Cannot get hostname. Exiting\n"); - GNUNET_free (hname); - GNUNET_free (dir); - GNUNET_SCHEDULER_shutdown (); - return; - } - GNUNET_asprintf (&fn, - "%s/%.*s_%jd.dat", - dir, - hname_len, - hname, - (intmax_t) pid); - GNUNET_free (hname); - GNUNET_free (dir); - if (NULL == (bio = GNUNET_BIO_write_open (fn))) - { - GNUNET_free (fn); - GNUNET_SCHEDULER_shutdown (); - return; - } - GNUNET_free (fn); - GNUNET_SERVER_add_handlers (server, message_handlers); - GNUNET_SERVER_connect_notify (server, &client_connected, NULL); - GNUNET_SERVER_disconnect_notify (server, &client_disconnected, NULL); - GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); - LOG_DEBUG ("TESTBED-LOGGER startup complete\n"); -} - - -/** - * The starting point of execution - */ -int -main (int argc, char *const *argv) -{ - return (GNUNET_OK == - GNUNET_SERVICE_run (argc, argv, "testbed-logger", - GNUNET_SERVICE_OPTION_NONE, - &logger_run, NULL)) ? 0 : 1; -} - -/* end of gnunet-service-testbed-logger.c */ diff --git a/src/testbed/test_testbed_logger_api.c b/src/testbed/test_testbed_logger_api.c deleted file mode 100644 index a25c0c5f0..000000000 --- a/src/testbed/test_testbed_logger_api.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - This file is part of GNUnet - Copyright (C) 2008--2013 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 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. - - 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. - */ -/** - * @file testbed/test_testbed_logger_api.c - * @brief testcases for the testbed logger api - * @author Sree Harsha Totakura - */ -#include "platform.h" -#include "gnunet_util_lib.h" -#include "gnunet_testing_lib.h" -#include "gnunet_testbed_logger_service.h" - -/** - * Generic logging shortcut - */ -#define LOG(kind,...) \ - GNUNET_log (kind, __VA_ARGS__) - -/** - * Relative time seconds shorthand - */ -#define TIME_REL_SECS(sec) \ - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec) - -/** - * Opaque handle for the logging service - */ -static struct GNUNET_TESTBED_LOGGER_Handle *h; - -static struct GNUNET_TESTING_Peer *peer; - -static char *search_dir; - -/** - * Abort task identifier - */ -static struct GNUNET_SCHEDULER_Task *abort_task; -static struct GNUNET_SCHEDULER_Task *write_task; - -static int result; - -#define CANCEL_TASK(task) do { \ - if (NULL != task) \ - { \ - GNUNET_SCHEDULER_cancel (task); \ - task = NULL; \ - } \ - } while (0) - -/** - * shortcut to exit during failure - */ -#define FAIL_TEST(cond, ret) do { \ - if (!(cond)) { \ - GNUNET_break(0); \ - CANCEL_TASK (abort_task); \ - abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL); \ - ret; \ - } \ - } while (0) - - -/** - * Shutdown nicely - * - * @param cls NULL - * @param tc the task context - */ -static void -shutdown_now () -{ - CANCEL_TASK (abort_task); - CANCEL_TASK (write_task); - GNUNET_free_non_null (search_dir); - if (NULL != h) - GNUNET_TESTBED_LOGGER_disconnect (h); - GNUNET_SCHEDULER_shutdown (); -} - - -static void -do_abort (void *cls) -{ - LOG (GNUNET_ERROR_TYPE_WARNING, - "Aborting\n"); - abort_task = NULL; - shutdown_now (); -} - - -#define BSIZE 1024 - - -/** - * Function called to iterate over a directory. - * - * @param cls closure - * @param filename complete filename (absolute path) - * @return #GNUNET_OK to continue to iterate, - * #GNUNET_NO to stop iteration with no error, - * #GNUNET_SYSERR to abort iteration with error! - */ -static int -iterator_cb (void *cls, - const char *filename) -{ - const char *fn; - size_t len; - uint64_t fs; - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Iterator sees file %s\n", - filename); - len = strlen (filename); - fn = filename + len; - if (0 != strcasecmp (".dat", fn - 4)) - return GNUNET_OK; - if (GNUNET_OK != - GNUNET_DISK_file_size (filename, - &fs, - GNUNET_NO, - GNUNET_YES)) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Failed to obtain file size for file %s\n", - filename); - return GNUNET_SYSERR; - } - if ((BSIZE * 2) != fs) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Unexpected file size for file %s\n", - filename); - /* The file size should be equal to what we - have written */ - return GNUNET_SYSERR; - } - result = GNUNET_OK; - return GNUNET_OK; -} - - -/** - * Functions of this type are called to notify a successful - * transmission of the message to the logger service - * - * @param cls the closure given to GNUNET_TESTBED_LOGGER_send() - * @param size the amount of data sent - */ -static void -flush_comp (void *cls, - size_t size) -{ - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Flush running\n"); - FAIL_TEST (&write_task == cls, - return); - FAIL_TEST ((BSIZE * 2) == size, - return); - FAIL_TEST (GNUNET_OK == - GNUNET_TESTING_peer_stop (peer), - return); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Peer stopped, scanning %s\n", - search_dir); - FAIL_TEST (GNUNET_SYSERR != - GNUNET_DISK_directory_scan (search_dir, - &iterator_cb, - NULL), - return); - shutdown_now (); -} - - -static void -do_write (void *cls) -{ - static int i; - char buf[BSIZE]; - - write_task = NULL; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Write task running\n"); - if (0 == i) - write_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS(1), - &do_write, - NULL); - (void) memset (buf, i, BSIZE); - GNUNET_TESTBED_LOGGER_write (h, - buf, - BSIZE); - if (0 == i++) - return; - GNUNET_TESTBED_LOGGER_flush (h, - GNUNET_TIME_UNIT_FOREVER_REL, - &flush_comp, - &write_task); -} - - -/** - * Signature of the 'main' function for a (single-peer) testcase that - * is run using #GNUNET_TESTING_peer_run(). - * - * @param cls closure - * @param cfg configuration of the peer that was started - * @param peer identity of the peer that was created - */ -static void -test_main (void *cls, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Peer *p) -{ - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Connecting to logger\n"); - FAIL_TEST (NULL != (h = GNUNET_TESTBED_LOGGER_connect (cfg)), - return); - FAIL_TEST (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_filename (cfg, - "testbed-logger", - "dir", - &search_dir), - return); - peer = p; - write_task = GNUNET_SCHEDULER_add_now (&do_write, - NULL); - abort_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (10), - &do_abort, - NULL); -} - - -/** - * Main function - */ -int -main (int argc, char **argv) -{ - int ret; - - result = GNUNET_SYSERR; - GNUNET_log_setup ("test-testbed-logger-api", - "WARNING", - NULL); - ret = GNUNET_TESTING_service_run ("test-testbed-logger", - "testbed-logger", - "test_testbed_logger_api.conf", - &test_main, - NULL); - if (0 != ret) - return 1; - if (GNUNET_OK != result) - return 2; - return 0; -} diff --git a/src/testbed/test_testbed_logger_api.conf b/src/testbed/test_testbed_logger_api.conf deleted file mode 100644 index 57ce5c254..000000000 --- a/src/testbed/test_testbed_logger_api.conf +++ /dev/null @@ -1,6 +0,0 @@ -[testbed-logger] -UNIXPATH=/tmp/testbed-logger.sock -DIR=$GNUNET_TEST_HOME/data - -[PATHS] -GNUNET_TEST_HOME = /tmp/test-testbed/ \ No newline at end of file diff --git a/src/testbed/testbed.conf.in b/src/testbed/testbed.conf.in index 094328c7b..86044fbfb 100644 --- a/src/testbed/testbed.conf.in +++ b/src/testbed/testbed.conf.in @@ -89,17 +89,6 @@ SETUP_TIMEOUT = 5 m SHARED_SERVICES = -[testbed-logger] -AUTOSTART = NO -@UNIXONLY@ PORT = 2102 -HOSTNAME = localhost -BINARY = gnunet-service-testbed-logger -UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-gnunet-testbed-logger.sock -DIR = /tmp -UNIX_MATCH_UID = YES -UNIX_MATCH_GID = YES - - [testbed-barrier] AUTOSTART = NO @UNIXONLY@ PORT = 2103 diff --git a/src/testbed/testbed_logger_api.c b/src/testbed/testbed_logger_api.c deleted file mode 100644 index aa182e21c..000000000 --- a/src/testbed/testbed_logger_api.c +++ /dev/null @@ -1,490 +0,0 @@ -/* - This file is part of GNUnet - Copyright (C) 2008--2013 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 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. - - 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. - */ - -/** - * @file testbed/testbed_logger_api.c - * @brief Client-side routines for communicating with the tesbted logger service - * @author Sree Harsha Totakura - */ - -#include "platform.h" -#include "gnunet_util_lib.h" -#include "gnunet_testbed_logger_service.h" - -/** - * Generic logging shorthand - */ -#define LOG(kind, ...) \ - GNUNET_log_from (kind, "testbed-logger-api", __VA_ARGS__) - -/** - * Debug logging - */ -#define LOG_DEBUG(...) \ - LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) - -#ifdef GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD -#undef GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD -#endif - -/** - * Threshold after which exponential backoff should not increase (15 s). - */ -#define GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3) - -/** - * The size of the buffer we fill before sending out the message - */ -#define BUFFER_SIZE GNUNET_SERVER_MAX_MESSAGE_SIZE - -/** - * The message queue for sending messages to the controller service - */ -struct MessageQueue -{ - /** - * next pointer for DLL - */ - struct MessageQueue *next; - - /** - * prev pointer for DLL - */ - struct MessageQueue *prev; - - /** - * The message to be sent - */ - struct GNUNET_MessageHeader *msg; - - /** - * Completion callback - */ - GNUNET_TESTBED_LOGGER_FlushCompletion cb; - - /** - * callback closure - */ - void *cb_cls; -}; - - -/** - * Connection handle for the logger service - */ -struct GNUNET_TESTBED_LOGGER_Handle -{ - /** - * Client connection - */ - struct GNUNET_CLIENT_Connection *client; - - /** - * The transport handle - */ - struct GNUNET_CLIENT_TransmitHandle *th; - - /** - * DLL head for the message queue - */ - struct MessageQueue *mq_head; - - /** - * DLL tail for the message queue - */ - struct MessageQueue *mq_tail; - - /** - * Flush completion callback - */ - GNUNET_TESTBED_LOGGER_FlushCompletion cb; - - /** - * Closure for the above callback - */ - void *cb_cls; - - /** - * Local buffer for data to be transmitted - */ - void *buf; - - /** - * The size of the local buffer - */ - size_t bs; - - /** - * Number of bytes wrote since last flush - */ - size_t bwrote; - - /** - * How long after should we retry sending a message to the service? - */ - struct GNUNET_TIME_Relative retry_backoff; - - /** - * Task to call the flush completion callback - */ - struct GNUNET_SCHEDULER_Task * flush_completion_task; - - /** - * Task to be executed when flushing takes too long - */ - struct GNUNET_SCHEDULER_Task * timeout_flush_task; -}; - - -/** - * Cancels the flush timeout task - * - * @param h handle to the logger - */ -static void -cancel_timeout_flush (struct GNUNET_TESTBED_LOGGER_Handle *h) -{ - GNUNET_SCHEDULER_cancel (h->timeout_flush_task); - h->timeout_flush_task = NULL; -} - - -/** - * Task to call the flush completion notification - * - * @param cls the logger handle - */ -static void -call_flush_completion (void *cls) -{ - struct GNUNET_TESTBED_LOGGER_Handle *h = cls; - GNUNET_TESTBED_LOGGER_FlushCompletion cb; - void *cb_cls; - size_t bw; - - h->flush_completion_task = NULL; - bw = h->bwrote; - h->bwrote = 0; - cb = h->cb; - h->cb = NULL; - cb_cls = h->cb_cls; - h->cb_cls = NULL; - if (NULL != h->timeout_flush_task) - cancel_timeout_flush (h); - if (NULL != cb) - cb (cb_cls, bw); -} - - -/** - * Schedule the flush completion notification task - * - * @param h logger handle - */ -static void -trigger_flush_notification (struct GNUNET_TESTBED_LOGGER_Handle *h) -{ - if (NULL != h->flush_completion_task) - GNUNET_SCHEDULER_cancel (h->flush_completion_task); - h->flush_completion_task = GNUNET_SCHEDULER_add_now (&call_flush_completion, h); -} - - -/** - * Function called to notify a client about the connection begin ready to queue - * more data. "buf" will be NULL and "size" zero if the connection was closed - * for writing in the meantime. - * - * @param cls closure - * @param size number of bytes available in buf - * @param buf where the callee should write the message - * @return number of bytes written to buf - */ -static size_t -transmit_ready_notify (void *cls, size_t size, void *buf) -{ - struct GNUNET_TESTBED_LOGGER_Handle *h = cls; - struct MessageQueue *mq; - - h->th = NULL; - mq = h->mq_head; - GNUNET_assert (NULL != mq); - if ((0 == size) && (NULL == buf)) /* Timeout */ - { - LOG_DEBUG ("Message sending timed out -- retrying\n"); - h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); - h->th = - GNUNET_CLIENT_notify_transmit_ready (h->client, - ntohs (mq->msg->size), - h->retry_backoff, GNUNET_YES, - &transmit_ready_notify, h); - return 0; - } - h->retry_backoff = GNUNET_TIME_UNIT_ZERO; - GNUNET_assert (ntohs (mq->msg->size) <= size); - size = ntohs (mq->msg->size); - memcpy (buf, mq->msg, size); - LOG_DEBUG ("Message of type: %u and size: %u sent\n", - ntohs (mq->msg->type), size); - GNUNET_free (mq->msg); - GNUNET_CONTAINER_DLL_remove (h->mq_head, h->mq_tail, mq); - GNUNET_free (mq); - h->bwrote += (size - sizeof (struct GNUNET_MessageHeader)); - mq = h->mq_head; - if (NULL != mq) - { - h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); - h->th = - GNUNET_CLIENT_notify_transmit_ready (h->client, - ntohs (mq->msg->size), - h->retry_backoff, GNUNET_YES, - &transmit_ready_notify, h); - return size; - } - if (NULL != h->cb) - trigger_flush_notification (h); /* Call the flush completion callback */ - return size; -} - - -/** - * Queues a message in send queue of the logger handle - * - * @param h the logger handle - * @param msg the message to queue - */ -static void -queue_message (struct GNUNET_TESTBED_LOGGER_Handle *h, - struct GNUNET_MessageHeader *msg) -{ - struct MessageQueue *mq; - uint16_t type; - uint16_t size; - - type = ntohs (msg->type); - size = ntohs (msg->size); - mq = GNUNET_new (struct MessageQueue); - mq->msg = msg; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Queueing message of type %u, size %u for sending\n", type, - ntohs (msg->size)); - GNUNET_CONTAINER_DLL_insert_tail (h->mq_head, h->mq_tail, mq); - if (NULL == h->th) - { - h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); - h->th = - GNUNET_CLIENT_notify_transmit_ready (h->client, size, - h->retry_backoff, GNUNET_YES, - &transmit_ready_notify, - h); - } -} - - -/** - * Send the buffered data to the service - * - * @param h the logger handle - */ -static void -dispatch_buffer (struct GNUNET_TESTBED_LOGGER_Handle *h) -{ - struct GNUNET_MessageHeader *msg; - size_t msize; - - msize = sizeof (struct GNUNET_MessageHeader) + h->bs; - msg = GNUNET_realloc (h->buf, msize); - h->buf = NULL; - memmove (&msg[1], msg, h->bs); - h->bs = 0; - msg->type = htons (GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG); - msg->size = htons (msize); - queue_message (h, msg); -} - - -/** - * Connect to the testbed logger service - * - * @param cfg configuration to use - * @return the handle which can be used for sending data to the service; NULL - * upon any error - */ -struct GNUNET_TESTBED_LOGGER_Handle * -GNUNET_TESTBED_LOGGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - struct GNUNET_TESTBED_LOGGER_Handle *h; - struct GNUNET_CLIENT_Connection *client; - - client = GNUNET_CLIENT_connect ("testbed-logger", cfg); - if (NULL == client) - return NULL; - h = GNUNET_new (struct GNUNET_TESTBED_LOGGER_Handle); - h->client = client; - return h; -} - - -/** - * Disconnect from the logger service. - * - * @param h the logger handle - */ -void -GNUNET_TESTBED_LOGGER_disconnect (struct GNUNET_TESTBED_LOGGER_Handle *h) -{ - struct MessageQueue *mq; - unsigned int lost; - - if (NULL != h->flush_completion_task) - GNUNET_SCHEDULER_cancel (h->flush_completion_task); - lost = 0; - while (NULL != (mq = h->mq_head)) - { - GNUNET_CONTAINER_DLL_remove (h->mq_head, h->mq_tail, mq); - GNUNET_free (mq->msg); - GNUNET_free (mq); - lost++; - } - if (0 != lost) - LOG (GNUNET_ERROR_TYPE_WARNING, "Cleaning up %u unsent logger message[s]\n", - lost); - GNUNET_CLIENT_disconnect (h->client); - GNUNET_free (h); -} - - -/** - * Send data to be logged to the logger service. The data will be buffered and - * will be sent upon an explicit call to GNUNET_TESTBED_LOGGER_flush() or upon - * exceeding a threshold size. - * - * @param h the logger handle - * @param data the data to send; - * @param size how many bytes of data to send - */ -void -GNUNET_TESTBED_LOGGER_write (struct GNUNET_TESTBED_LOGGER_Handle *h, - const void *data, size_t size) -{ - size_t fit_size; - - GNUNET_assert (0 != size); - GNUNET_assert (NULL != data); - GNUNET_assert (size <= (BUFFER_SIZE - sizeof (struct GNUNET_MessageHeader))); - fit_size = sizeof (struct GNUNET_MessageHeader) + h->bs + size; - if ( BUFFER_SIZE < fit_size ) - dispatch_buffer (h); - if (NULL == h->buf) - { - h->buf = GNUNET_malloc (size); - h->bs = size; - memcpy (h->buf, data, size); - goto dispatch_ready; - } - h->buf = GNUNET_realloc (h->buf, h->bs + size); - memcpy (h->buf + h->bs, data, size); - h->bs += size; - - dispatch_ready: - if (BUFFER_SIZE == fit_size) - dispatch_buffer (h); -} - - -/** - * Task to be executed when flushing our local buffer takes longer than timeout - * given to GNUNET_TESTBED_LOGGER_flush(). The flush completion callback will - * be called with 0 as the amount of data sent. - * - * @param cls the logger handle - */ -static void -timeout_flush (void *cls) -{ - struct GNUNET_TESTBED_LOGGER_Handle *h = cls; - GNUNET_TESTBED_LOGGER_FlushCompletion cb; - void *cb_cls; - - h->timeout_flush_task = NULL; - cb = h->cb; - h->cb = NULL; - cb_cls = h->cb_cls; - h->cb_cls = NULL; - if (NULL != h->flush_completion_task) - { - GNUNET_SCHEDULER_cancel (h->flush_completion_task); - h->flush_completion_task = NULL; - } - if (NULL != cb) - cb (cb_cls, 0); -} - - -/** - * Flush the buffered data to the logger service - * - * @param h the logger handle - * @param timeout how long to wait before calling the flust completion callback - * @param cb the callback to call after the data is flushed - * @param cb_cls the closure for the above callback - */ -void -GNUNET_TESTBED_LOGGER_flush (struct GNUNET_TESTBED_LOGGER_Handle *h, - struct GNUNET_TIME_Relative timeout, - GNUNET_TESTBED_LOGGER_FlushCompletion cb, - void *cb_cls) -{ - h->cb = cb; - h->cb_cls = cb_cls; - GNUNET_assert (NULL == h->timeout_flush_task); - h->timeout_flush_task = - GNUNET_SCHEDULER_add_delayed (timeout, &timeout_flush, h); - if (NULL == h->buf) - { - trigger_flush_notification (h); - return; - } - dispatch_buffer (h); -} - - -/** - * Cancel notification upon flush. Should only be used when the flush - * completion callback given to GNUNET_TESTBED_LOGGER_flush() is not already - * called. - * - * @param h the logger handle - */ -void -GNUNET_TESTBED_LOGGER_flush_cancel (struct GNUNET_TESTBED_LOGGER_Handle *h) -{ - if (NULL != h->flush_completion_task) - { - GNUNET_SCHEDULER_cancel (h->flush_completion_task); - h->flush_completion_task = NULL; - } - if (NULL != h->timeout_flush_task) - cancel_timeout_flush (h); - h->cb = NULL; - h->cb_cls = NULL; -} - -/* End of testbed_logger_api.c */ -- cgit v1.2.3