aboutsummaryrefslogtreecommitdiff
path: root/src/testbed
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-06-24 14:05:58 +0000
committerChristian Grothoff <christian@grothoff.org>2016-06-24 14:05:58 +0000
commit71c68d0bbdb546bfe84b4536b447899c53cb3812 (patch)
treecbde440932f0b8c038a6559f880a9ecb0de719d9 /src/testbed
parent7093450cf4d9e0654a128aaff442fc6f6809326e (diff)
downloadgnunet-71c68d0bbdb546bfe84b4536b447899c53cb3812.tar.gz
gnunet-71c68d0bbdb546bfe84b4536b447899c53cb3812.zip
move testbed logger to its own directory
Diffstat (limited to 'src/testbed')
-rw-r--r--src/testbed/Makefile.am28
-rw-r--r--src/testbed/gnunet-service-testbed-logger.c270
-rw-r--r--src/testbed/test_testbed_logger_api.c272
-rw-r--r--src/testbed/test_testbed_logger_api.conf6
-rw-r--r--src/testbed/testbed.conf.in11
-rw-r--r--src/testbed/testbed_logger_api.c490
6 files changed, 1 insertions, 1076 deletions
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
27libexec_PROGRAMS = \ 27libexec_PROGRAMS = \
28 gnunet-service-testbed \ 28 gnunet-service-testbed \
29 gnunet-helper-testbed \ 29 gnunet-helper-testbed \
30 gnunet-service-testbed-logger \
31 gnunet-daemon-testbed-blacklist \ 30 gnunet-daemon-testbed-blacklist \
32 $(underlay_daemon) \ 31 $(underlay_daemon) \
33 $(latency_logger) 32 $(latency_logger)
@@ -59,11 +58,6 @@ gnunet_service_testbed_LDADD = $(XLIB) \
59 $(top_builddir)/src/arm/libgnunetarm.la \ 58 $(top_builddir)/src/arm/libgnunetarm.la \
60 $(LTLIBINTL) $(Z_LIBS) 59 $(LTLIBINTL) $(Z_LIBS)
61 60
62gnunet_service_testbed_logger_SOURCES = \
63 gnunet-service-testbed-logger.c
64gnunet_service_testbed_logger_LDADD = \
65 $(top_builddir)/src/util/libgnunetutil.la
66
67gnunet_testbed_profiler_SOURCES = \ 61gnunet_testbed_profiler_SOURCES = \
68 gnunet-testbed-profiler.c 62 gnunet-testbed-profiler.c
69gnunet_testbed_profiler_LDADD = $(XLIB) \ 63gnunet_testbed_profiler_LDADD = $(XLIB) \
@@ -97,8 +91,7 @@ gnunet_daemon_latency_logger_LDADD = $(XLIB) \
97 $(LTLIBINTL) -lsqlite3 91 $(LTLIBINTL) -lsqlite3
98 92
99lib_LTLIBRARIES = \ 93lib_LTLIBRARIES = \
100 libgnunettestbed.la \ 94 libgnunettestbed.la
101 libgnunettestbedlogger.la
102 95
103libgnunettestbed_la_SOURCES = \ 96libgnunettestbed_la_SOURCES = \
104 testbed_api.c testbed_api.h testbed.h \ 97 testbed_api.c testbed_api.h testbed.h \
@@ -125,15 +118,6 @@ libgnunettestbed_la_LDFLAGS = \
125 $(GN_LIB_LDFLAGS) \ 118 $(GN_LIB_LDFLAGS) \
126 -version-info 0:0:0 119 -version-info 0:0:0
127 120
128libgnunettestbedlogger_la_SOURCES = \
129 testbed_logger_api.c
130libgnunettestbedlogger_la_LIBADD = $(XLIB) \
131 $(top_builddir)/src/util/libgnunetutil.la \
132 $(LTLIBINTL)
133libgnunettestbedlogger_la_LDFLAGS = \
134 $(GN_LIB_LDFLAGS) \
135 -version-info 0:0:0
136
137generate_underlay_topology_SOURCES = generate-underlay-topology.c 121generate_underlay_topology_SOURCES = generate-underlay-topology.c
138generate_underlay_topology_LDADD = $(XLIB) \ 122generate_underlay_topology_LDADD = $(XLIB) \
139 $(top_builddir)/src/util/libgnunetutil.la \ 123 $(top_builddir)/src/util/libgnunetutil.la \
@@ -142,7 +126,6 @@ generate_underlay_topology_LDADD = $(XLIB) \
142 126
143check_PROGRAMS = \ 127check_PROGRAMS = \
144 test_testbed_api_hosts \ 128 test_testbed_api_hosts \
145 test_testbed_logger_api \
146 test_gnunet_helper_testbed \ 129 test_gnunet_helper_testbed \
147 test_testbed_api_controllerlink \ 130 test_testbed_api_controllerlink \
148 test_testbed_api_2peers_1controller \ 131 test_testbed_api_2peers_1controller \
@@ -176,7 +159,6 @@ if ENABLE_TEST_RUN
176 AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; 159 AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;
177 TESTS = \ 160 TESTS = \
178 test_testbed_api \ 161 test_testbed_api \
179 test_testbed_logger_api \
180 test_testbed_api_sd \ 162 test_testbed_api_sd \
181 test_testbed_api_operations \ 163 test_testbed_api_operations \
182 test_testbed_api_hosts \ 164 test_testbed_api_hosts \
@@ -219,13 +201,6 @@ test_testbed_api_LDADD = \
219 $(top_builddir)/src/arm/libgnunetarm.la \ 201 $(top_builddir)/src/arm/libgnunetarm.la \
220 libgnunettestbed.la 202 libgnunettestbed.la
221 203
222test_testbed_logger_api_SOURCES = \
223 test_testbed_logger_api.c
224test_testbed_logger_api_LDADD = \
225 $(top_builddir)/src/util/libgnunetutil.la \
226 $(top_builddir)/src/testing/libgnunettesting.la \
227 libgnunettestbedlogger.la
228
229test_testbed_api_sd_SOURCES = \ 204test_testbed_api_sd_SOURCES = \
230 test_testbed_api_sd.c 205 test_testbed_api_sd.c
231test_testbed_api_sd_LDADD = \ 206test_testbed_api_sd_LDADD = \
@@ -398,7 +373,6 @@ EXTRA_DIST = \
398 test_testbed_api_statistics.conf \ 373 test_testbed_api_statistics.conf \
399 test_testbed_api_test_timeout.conf \ 374 test_testbed_api_test_timeout.conf \
400 test_testbed_api_template.conf \ 375 test_testbed_api_template.conf \
401 test_testbed_logger_api.conf \
402 test_testbed_api_testbed_run_topologyring.conf \ 376 test_testbed_api_testbed_run_topologyring.conf \
403 test_testbed_api_testbed_run_topologyclique.conf \ 377 test_testbed_api_testbed_run_topologyclique.conf \
404 test_testbed_api_testbed_run_topologyline.conf \ 378 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 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2008--2013 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file testbed/gnunet-service-testbed-logger.c
23 * @brief service for collecting messages and writing to a file
24 * @author Sree Harsha Totakura
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29
30/**
31 * Generic logging shorthand
32 */
33#define LOG(type, ...) \
34 GNUNET_log (type, __VA_ARGS__)
35
36/**
37 * Debug logging shorthand
38 */
39#define LOG_DEBUG(...) \
40 LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
41
42/**
43 * The message queue for sending messages to clients
44 */
45struct MessageQueue
46{
47 /**
48 * The message to be sent
49 */
50 struct GNUNET_MessageHeader *msg;
51
52 /**
53 * The client to send the message to
54 */
55 struct GNUNET_SERVER_Client *client;
56
57 /**
58 * next pointer for DLL
59 */
60 struct MessageQueue *next;
61
62 /**
63 * prev pointer for DLL
64 */
65 struct MessageQueue *prev;
66};
67
68/**
69 * The message queue head
70 */
71static struct MessageQueue *mq_head;
72
73/**
74 * The message queue tail
75 */
76static struct MessageQueue *mq_tail;
77
78/**
79 * Handle for buffered writing.
80 */
81struct GNUNET_BIO_WriteHandle *bio;
82
83/**
84 * The number of connections we have
85 */
86static unsigned int nconn;
87
88/**
89 * Are we shutting down?
90 */
91static int in_shutdown;
92
93
94/**
95 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST messages
96 *
97 * @param cls NULL
98 * @param client identification of the client
99 * @param msg the actual message
100 */
101static void
102handle_log_msg (void *cls,
103 struct GNUNET_SERVER_Client *client,
104 const struct GNUNET_MessageHeader *msg)
105{
106 uint16_t ms;
107
108 ms = ntohs (msg->size);
109 ms -= sizeof (struct GNUNET_MessageHeader);
110 GNUNET_BIO_write (bio, &msg[1], ms);
111 GNUNET_SERVER_receive_done (client, GNUNET_OK);
112}
113
114
115/**
116 * Task to clean up and shutdown nicely
117 *
118 * @param cls NULL
119 */
120static void
121shutdown_task (void *cls)
122{
123 struct MessageQueue *mq_entry;
124
125 in_shutdown = GNUNET_YES;
126 if (0 != nconn)
127 {
128 /* Delay shutdown if there are active connections */
129 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
130 return;
131 }
132 while (NULL != (mq_entry = mq_head))
133 {
134 GNUNET_free (mq_entry->msg);
135 GNUNET_SERVER_client_drop (mq_entry->client);
136 GNUNET_CONTAINER_DLL_remove (mq_head,
137 mq_tail,
138 mq_entry);
139 GNUNET_free (mq_entry);
140 }
141 GNUNET_break (GNUNET_OK == GNUNET_BIO_write_close (bio));
142}
143
144
145/**
146x * Functions with this signature are called whenever a client
147 * is disconnected on the network level.
148 *
149 * @param cls closure
150 * @param client identification of the client; NULL
151 * for the last call when the server is destroyed
152 */
153static void
154client_disconnected (void *cls,
155 struct GNUNET_SERVER_Client *client)
156{
157 if (NULL == client)
158 {
159 GNUNET_break (0 == nconn);
160 return;
161 }
162 nconn--;
163 if (GNUNET_YES == in_shutdown)
164 GNUNET_SCHEDULER_shutdown ();
165}
166
167
168/**
169 * Functions with this signature are called whenever a client
170 * is connected on the network level.
171 *
172 * @param cls closure
173 * @param client identification of the client
174 */
175static void
176client_connected (void *cls,
177 struct GNUNET_SERVER_Client *client)
178{
179 if (NULL == client)
180 {
181 GNUNET_break (0 == nconn);
182 return;
183 }
184 GNUNET_SERVER_client_persist_ (client);
185 nconn++;
186}
187
188
189/**
190 * Testbed setup
191 *
192 * @param cls closure
193 * @param server the initialized server
194 * @param cfg configuration to use
195 */
196static void
197logger_run (void *cls,
198 struct GNUNET_SERVER_Handle *server,
199 const struct GNUNET_CONFIGURATION_Handle *cfg)
200{
201 static const struct GNUNET_SERVER_MessageHandler message_handlers[] = {
202 {&handle_log_msg, NULL, GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG, 0},
203 {NULL, NULL, 0, 0}
204 };
205 char *dir;
206 char *fn;
207 char *hname;
208 size_t hname_len;
209 pid_t pid;
210
211 if (GNUNET_OK !=
212 GNUNET_CONFIGURATION_get_value_filename (cfg,
213 "TESTBED-LOGGER",
214 "DIR",
215 &dir))
216 {
217 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
218 "TESTBED-LOGGER",
219 "DIR");
220 GNUNET_SCHEDULER_shutdown ();
221 return;
222 }
223 pid = getpid ();
224 hname_len = GNUNET_OS_get_hostname_max_length ();
225 hname = GNUNET_malloc (hname_len);
226 if (0 != gethostname (hname, hname_len))
227 {
228 LOG (GNUNET_ERROR_TYPE_ERROR,
229 "Cannot get hostname. Exiting\n");
230 GNUNET_free (hname);
231 GNUNET_free (dir);
232 GNUNET_SCHEDULER_shutdown ();
233 return;
234 }
235 GNUNET_asprintf (&fn,
236 "%s/%.*s_%jd.dat",
237 dir,
238 hname_len,
239 hname,
240 (intmax_t) pid);
241 GNUNET_free (hname);
242 GNUNET_free (dir);
243 if (NULL == (bio = GNUNET_BIO_write_open (fn)))
244 {
245 GNUNET_free (fn);
246 GNUNET_SCHEDULER_shutdown ();
247 return;
248 }
249 GNUNET_free (fn);
250 GNUNET_SERVER_add_handlers (server, message_handlers);
251 GNUNET_SERVER_connect_notify (server, &client_connected, NULL);
252 GNUNET_SERVER_disconnect_notify (server, &client_disconnected, NULL);
253 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
254 LOG_DEBUG ("TESTBED-LOGGER startup complete\n");
255}
256
257
258/**
259 * The starting point of execution
260 */
261int
262main (int argc, char *const *argv)
263{
264 return (GNUNET_OK ==
265 GNUNET_SERVICE_run (argc, argv, "testbed-logger",
266 GNUNET_SERVICE_OPTION_NONE,
267 &logger_run, NULL)) ? 0 : 1;
268}
269
270/* 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 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2008--2013 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19 */
20/**
21 * @file testbed/test_testbed_logger_api.c
22 * @brief testcases for the testbed logger api
23 * @author Sree Harsha Totakura
24 */
25#include "platform.h"
26#include "gnunet_util_lib.h"
27#include "gnunet_testing_lib.h"
28#include "gnunet_testbed_logger_service.h"
29
30/**
31 * Generic logging shortcut
32 */
33#define LOG(kind,...) \
34 GNUNET_log (kind, __VA_ARGS__)
35
36/**
37 * Relative time seconds shorthand
38 */
39#define TIME_REL_SECS(sec) \
40 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec)
41
42/**
43 * Opaque handle for the logging service
44 */
45static struct GNUNET_TESTBED_LOGGER_Handle *h;
46
47static struct GNUNET_TESTING_Peer *peer;
48
49static char *search_dir;
50
51/**
52 * Abort task identifier
53 */
54static struct GNUNET_SCHEDULER_Task *abort_task;
55static struct GNUNET_SCHEDULER_Task *write_task;
56
57static int result;
58
59#define CANCEL_TASK(task) do { \
60 if (NULL != task) \
61 { \
62 GNUNET_SCHEDULER_cancel (task); \
63 task = NULL; \
64 } \
65 } while (0)
66
67/**
68 * shortcut to exit during failure
69 */
70#define FAIL_TEST(cond, ret) do { \
71 if (!(cond)) { \
72 GNUNET_break(0); \
73 CANCEL_TASK (abort_task); \
74 abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL); \
75 ret; \
76 } \
77 } while (0)
78
79
80/**
81 * Shutdown nicely
82 *
83 * @param cls NULL
84 * @param tc the task context
85 */
86static void
87shutdown_now ()
88{
89 CANCEL_TASK (abort_task);
90 CANCEL_TASK (write_task);
91 GNUNET_free_non_null (search_dir);
92 if (NULL != h)
93 GNUNET_TESTBED_LOGGER_disconnect (h);
94 GNUNET_SCHEDULER_shutdown ();
95}
96
97
98static void
99do_abort (void *cls)
100{
101 LOG (GNUNET_ERROR_TYPE_WARNING,
102 "Aborting\n");
103 abort_task = NULL;
104 shutdown_now ();
105}
106
107
108#define BSIZE 1024
109
110
111/**
112 * Function called to iterate over a directory.
113 *
114 * @param cls closure
115 * @param filename complete filename (absolute path)
116 * @return #GNUNET_OK to continue to iterate,
117 * #GNUNET_NO to stop iteration with no error,
118 * #GNUNET_SYSERR to abort iteration with error!
119 */
120static int
121iterator_cb (void *cls,
122 const char *filename)
123{
124 const char *fn;
125 size_t len;
126 uint64_t fs;
127
128 LOG (GNUNET_ERROR_TYPE_DEBUG,
129 "Iterator sees file %s\n",
130 filename);
131 len = strlen (filename);
132 fn = filename + len;
133 if (0 != strcasecmp (".dat", fn - 4))
134 return GNUNET_OK;
135 if (GNUNET_OK !=
136 GNUNET_DISK_file_size (filename,
137 &fs,
138 GNUNET_NO,
139 GNUNET_YES))
140 {
141 LOG (GNUNET_ERROR_TYPE_DEBUG,
142 "Failed to obtain file size for file %s\n",
143 filename);
144 return GNUNET_SYSERR;
145 }
146 if ((BSIZE * 2) != fs)
147 {
148 LOG (GNUNET_ERROR_TYPE_DEBUG,
149 "Unexpected file size for file %s\n",
150 filename);
151 /* The file size should be equal to what we
152 have written */
153 return GNUNET_SYSERR;
154 }
155 result = GNUNET_OK;
156 return GNUNET_OK;
157}
158
159
160/**
161 * Functions of this type are called to notify a successful
162 * transmission of the message to the logger service
163 *
164 * @param cls the closure given to GNUNET_TESTBED_LOGGER_send()
165 * @param size the amount of data sent
166 */
167static void
168flush_comp (void *cls,
169 size_t size)
170{
171 LOG (GNUNET_ERROR_TYPE_DEBUG,
172 "Flush running\n");
173 FAIL_TEST (&write_task == cls,
174 return);
175 FAIL_TEST ((BSIZE * 2) == size,
176 return);
177 FAIL_TEST (GNUNET_OK ==
178 GNUNET_TESTING_peer_stop (peer),
179 return);
180 LOG (GNUNET_ERROR_TYPE_DEBUG,
181 "Peer stopped, scanning %s\n",
182 search_dir);
183 FAIL_TEST (GNUNET_SYSERR !=
184 GNUNET_DISK_directory_scan (search_dir,
185 &iterator_cb,
186 NULL),
187 return);
188 shutdown_now ();
189}
190
191
192static void
193do_write (void *cls)
194{
195 static int i;
196 char buf[BSIZE];
197
198 write_task = NULL;
199 LOG (GNUNET_ERROR_TYPE_DEBUG,
200 "Write task running\n");
201 if (0 == i)
202 write_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS(1),
203 &do_write,
204 NULL);
205 (void) memset (buf, i, BSIZE);
206 GNUNET_TESTBED_LOGGER_write (h,
207 buf,
208 BSIZE);
209 if (0 == i++)
210 return;
211 GNUNET_TESTBED_LOGGER_flush (h,
212 GNUNET_TIME_UNIT_FOREVER_REL,
213 &flush_comp,
214 &write_task);
215}
216
217
218/**
219 * Signature of the 'main' function for a (single-peer) testcase that
220 * is run using #GNUNET_TESTING_peer_run().
221 *
222 * @param cls closure
223 * @param cfg configuration of the peer that was started
224 * @param peer identity of the peer that was created
225 */
226static void
227test_main (void *cls,
228 const struct GNUNET_CONFIGURATION_Handle *cfg,
229 struct GNUNET_TESTING_Peer *p)
230{
231 LOG (GNUNET_ERROR_TYPE_DEBUG,
232 "Connecting to logger\n");
233 FAIL_TEST (NULL != (h = GNUNET_TESTBED_LOGGER_connect (cfg)),
234 return);
235 FAIL_TEST (GNUNET_OK ==
236 GNUNET_CONFIGURATION_get_value_filename (cfg,
237 "testbed-logger",
238 "dir",
239 &search_dir),
240 return);
241 peer = p;
242 write_task = GNUNET_SCHEDULER_add_now (&do_write,
243 NULL);
244 abort_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (10),
245 &do_abort,
246 NULL);
247}
248
249
250/**
251 * Main function
252 */
253int
254main (int argc, char **argv)
255{
256 int ret;
257
258 result = GNUNET_SYSERR;
259 GNUNET_log_setup ("test-testbed-logger-api",
260 "WARNING",
261 NULL);
262 ret = GNUNET_TESTING_service_run ("test-testbed-logger",
263 "testbed-logger",
264 "test_testbed_logger_api.conf",
265 &test_main,
266 NULL);
267 if (0 != ret)
268 return 1;
269 if (GNUNET_OK != result)
270 return 2;
271 return 0;
272}
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 @@
1[testbed-logger]
2UNIXPATH=/tmp/testbed-logger.sock
3DIR=$GNUNET_TEST_HOME/data
4
5[PATHS]
6GNUNET_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
89SHARED_SERVICES = 89SHARED_SERVICES =
90 90
91 91
92[testbed-logger]
93AUTOSTART = NO
94@UNIXONLY@ PORT = 2102
95HOSTNAME = localhost
96BINARY = gnunet-service-testbed-logger
97UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-gnunet-testbed-logger.sock
98DIR = /tmp
99UNIX_MATCH_UID = YES
100UNIX_MATCH_GID = YES
101
102
103[testbed-barrier] 92[testbed-barrier]
104AUTOSTART = NO 93AUTOSTART = NO
105@UNIXONLY@ PORT = 2103 94@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 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2008--2013 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19 */
20
21/**
22 * @file testbed/testbed_logger_api.c
23 * @brief Client-side routines for communicating with the tesbted logger service
24 * @author Sree Harsha Totakura <sreeharsha@totakura.in>
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_testbed_logger_service.h"
30
31/**
32 * Generic logging shorthand
33 */
34#define LOG(kind, ...) \
35 GNUNET_log_from (kind, "testbed-logger-api", __VA_ARGS__)
36
37/**
38 * Debug logging
39 */
40#define LOG_DEBUG(...) \
41 LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
42
43#ifdef GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD
44#undef GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD
45#endif
46
47/**
48 * Threshold after which exponential backoff should not increase (15 s).
49 */
50#define GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
51
52/**
53 * The size of the buffer we fill before sending out the message
54 */
55#define BUFFER_SIZE GNUNET_SERVER_MAX_MESSAGE_SIZE
56
57/**
58 * The message queue for sending messages to the controller service
59 */
60struct MessageQueue
61{
62 /**
63 * next pointer for DLL
64 */
65 struct MessageQueue *next;
66
67 /**
68 * prev pointer for DLL
69 */
70 struct MessageQueue *prev;
71
72 /**
73 * The message to be sent
74 */
75 struct GNUNET_MessageHeader *msg;
76
77 /**
78 * Completion callback
79 */
80 GNUNET_TESTBED_LOGGER_FlushCompletion cb;
81
82 /**
83 * callback closure
84 */
85 void *cb_cls;
86};
87
88
89/**
90 * Connection handle for the logger service
91 */
92struct GNUNET_TESTBED_LOGGER_Handle
93{
94 /**
95 * Client connection
96 */
97 struct GNUNET_CLIENT_Connection *client;
98
99 /**
100 * The transport handle
101 */
102 struct GNUNET_CLIENT_TransmitHandle *th;
103
104 /**
105 * DLL head for the message queue
106 */
107 struct MessageQueue *mq_head;
108
109 /**
110 * DLL tail for the message queue
111 */
112 struct MessageQueue *mq_tail;
113
114 /**
115 * Flush completion callback
116 */
117 GNUNET_TESTBED_LOGGER_FlushCompletion cb;
118
119 /**
120 * Closure for the above callback
121 */
122 void *cb_cls;
123
124 /**
125 * Local buffer for data to be transmitted
126 */
127 void *buf;
128
129 /**
130 * The size of the local buffer
131 */
132 size_t bs;
133
134 /**
135 * Number of bytes wrote since last flush
136 */
137 size_t bwrote;
138
139 /**
140 * How long after should we retry sending a message to the service?
141 */
142 struct GNUNET_TIME_Relative retry_backoff;
143
144 /**
145 * Task to call the flush completion callback
146 */
147 struct GNUNET_SCHEDULER_Task * flush_completion_task;
148
149 /**
150 * Task to be executed when flushing takes too long
151 */
152 struct GNUNET_SCHEDULER_Task * timeout_flush_task;
153};
154
155
156/**
157 * Cancels the flush timeout task
158 *
159 * @param h handle to the logger
160 */
161static void
162cancel_timeout_flush (struct GNUNET_TESTBED_LOGGER_Handle *h)
163{
164 GNUNET_SCHEDULER_cancel (h->timeout_flush_task);
165 h->timeout_flush_task = NULL;
166}
167
168
169/**
170 * Task to call the flush completion notification
171 *
172 * @param cls the logger handle
173 */
174static void
175call_flush_completion (void *cls)
176{
177 struct GNUNET_TESTBED_LOGGER_Handle *h = cls;
178 GNUNET_TESTBED_LOGGER_FlushCompletion cb;
179 void *cb_cls;
180 size_t bw;
181
182 h->flush_completion_task = NULL;
183 bw = h->bwrote;
184 h->bwrote = 0;
185 cb = h->cb;
186 h->cb = NULL;
187 cb_cls = h->cb_cls;
188 h->cb_cls = NULL;
189 if (NULL != h->timeout_flush_task)
190 cancel_timeout_flush (h);
191 if (NULL != cb)
192 cb (cb_cls, bw);
193}
194
195
196/**
197 * Schedule the flush completion notification task
198 *
199 * @param h logger handle
200 */
201static void
202trigger_flush_notification (struct GNUNET_TESTBED_LOGGER_Handle *h)
203{
204 if (NULL != h->flush_completion_task)
205 GNUNET_SCHEDULER_cancel (h->flush_completion_task);
206 h->flush_completion_task = GNUNET_SCHEDULER_add_now (&call_flush_completion, h);
207}
208
209
210/**
211 * Function called to notify a client about the connection begin ready to queue
212 * more data. "buf" will be NULL and "size" zero if the connection was closed
213 * for writing in the meantime.
214 *
215 * @param cls closure
216 * @param size number of bytes available in buf
217 * @param buf where the callee should write the message
218 * @return number of bytes written to buf
219 */
220static size_t
221transmit_ready_notify (void *cls, size_t size, void *buf)
222{
223 struct GNUNET_TESTBED_LOGGER_Handle *h = cls;
224 struct MessageQueue *mq;
225
226 h->th = NULL;
227 mq = h->mq_head;
228 GNUNET_assert (NULL != mq);
229 if ((0 == size) && (NULL == buf)) /* Timeout */
230 {
231 LOG_DEBUG ("Message sending timed out -- retrying\n");
232 h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
233 h->th =
234 GNUNET_CLIENT_notify_transmit_ready (h->client,
235 ntohs (mq->msg->size),
236 h->retry_backoff, GNUNET_YES,
237 &transmit_ready_notify, h);
238 return 0;
239 }
240 h->retry_backoff = GNUNET_TIME_UNIT_ZERO;
241 GNUNET_assert (ntohs (mq->msg->size) <= size);
242 size = ntohs (mq->msg->size);
243 memcpy (buf, mq->msg, size);
244 LOG_DEBUG ("Message of type: %u and size: %u sent\n",
245 ntohs (mq->msg->type), size);
246 GNUNET_free (mq->msg);
247 GNUNET_CONTAINER_DLL_remove (h->mq_head, h->mq_tail, mq);
248 GNUNET_free (mq);
249 h->bwrote += (size - sizeof (struct GNUNET_MessageHeader));
250 mq = h->mq_head;
251 if (NULL != mq)
252 {
253 h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
254 h->th =
255 GNUNET_CLIENT_notify_transmit_ready (h->client,
256 ntohs (mq->msg->size),
257 h->retry_backoff, GNUNET_YES,
258 &transmit_ready_notify, h);
259 return size;
260 }
261 if (NULL != h->cb)
262 trigger_flush_notification (h); /* Call the flush completion callback */
263 return size;
264}
265
266
267/**
268 * Queues a message in send queue of the logger handle
269 *
270 * @param h the logger handle
271 * @param msg the message to queue
272 */
273static void
274queue_message (struct GNUNET_TESTBED_LOGGER_Handle *h,
275 struct GNUNET_MessageHeader *msg)
276{
277 struct MessageQueue *mq;
278 uint16_t type;
279 uint16_t size;
280
281 type = ntohs (msg->type);
282 size = ntohs (msg->size);
283 mq = GNUNET_new (struct MessageQueue);
284 mq->msg = msg;
285 LOG (GNUNET_ERROR_TYPE_DEBUG,
286 "Queueing message of type %u, size %u for sending\n", type,
287 ntohs (msg->size));
288 GNUNET_CONTAINER_DLL_insert_tail (h->mq_head, h->mq_tail, mq);
289 if (NULL == h->th)
290 {
291 h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
292 h->th =
293 GNUNET_CLIENT_notify_transmit_ready (h->client, size,
294 h->retry_backoff, GNUNET_YES,
295 &transmit_ready_notify,
296 h);
297 }
298}
299
300
301/**
302 * Send the buffered data to the service
303 *
304 * @param h the logger handle
305 */
306static void
307dispatch_buffer (struct GNUNET_TESTBED_LOGGER_Handle *h)
308{
309 struct GNUNET_MessageHeader *msg;
310 size_t msize;
311
312 msize = sizeof (struct GNUNET_MessageHeader) + h->bs;
313 msg = GNUNET_realloc (h->buf, msize);
314 h->buf = NULL;
315 memmove (&msg[1], msg, h->bs);
316 h->bs = 0;
317 msg->type = htons (GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG);
318 msg->size = htons (msize);
319 queue_message (h, msg);
320}
321
322
323/**
324 * Connect to the testbed logger service
325 *
326 * @param cfg configuration to use
327 * @return the handle which can be used for sending data to the service; NULL
328 * upon any error
329 */
330struct GNUNET_TESTBED_LOGGER_Handle *
331GNUNET_TESTBED_LOGGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
332{
333 struct GNUNET_TESTBED_LOGGER_Handle *h;
334 struct GNUNET_CLIENT_Connection *client;
335
336 client = GNUNET_CLIENT_connect ("testbed-logger", cfg);
337 if (NULL == client)
338 return NULL;
339 h = GNUNET_new (struct GNUNET_TESTBED_LOGGER_Handle);
340 h->client = client;
341 return h;
342}
343
344
345/**
346 * Disconnect from the logger service.
347 *
348 * @param h the logger handle
349 */
350void
351GNUNET_TESTBED_LOGGER_disconnect (struct GNUNET_TESTBED_LOGGER_Handle *h)
352{
353 struct MessageQueue *mq;
354 unsigned int lost;
355
356 if (NULL != h->flush_completion_task)
357 GNUNET_SCHEDULER_cancel (h->flush_completion_task);
358 lost = 0;
359 while (NULL != (mq = h->mq_head))
360 {
361 GNUNET_CONTAINER_DLL_remove (h->mq_head, h->mq_tail, mq);
362 GNUNET_free (mq->msg);
363 GNUNET_free (mq);
364 lost++;
365 }
366 if (0 != lost)
367 LOG (GNUNET_ERROR_TYPE_WARNING, "Cleaning up %u unsent logger message[s]\n",
368 lost);
369 GNUNET_CLIENT_disconnect (h->client);
370 GNUNET_free (h);
371}
372
373
374/**
375 * Send data to be logged to the logger service. The data will be buffered and
376 * will be sent upon an explicit call to GNUNET_TESTBED_LOGGER_flush() or upon
377 * exceeding a threshold size.
378 *
379 * @param h the logger handle
380 * @param data the data to send;
381 * @param size how many bytes of data to send
382 */
383void
384GNUNET_TESTBED_LOGGER_write (struct GNUNET_TESTBED_LOGGER_Handle *h,
385 const void *data, size_t size)
386{
387 size_t fit_size;
388
389 GNUNET_assert (0 != size);
390 GNUNET_assert (NULL != data);
391 GNUNET_assert (size <= (BUFFER_SIZE - sizeof (struct GNUNET_MessageHeader)));
392 fit_size = sizeof (struct GNUNET_MessageHeader) + h->bs + size;
393 if ( BUFFER_SIZE < fit_size )
394 dispatch_buffer (h);
395 if (NULL == h->buf)
396 {
397 h->buf = GNUNET_malloc (size);
398 h->bs = size;
399 memcpy (h->buf, data, size);
400 goto dispatch_ready;
401 }
402 h->buf = GNUNET_realloc (h->buf, h->bs + size);
403 memcpy (h->buf + h->bs, data, size);
404 h->bs += size;
405
406 dispatch_ready:
407 if (BUFFER_SIZE == fit_size)
408 dispatch_buffer (h);
409}
410
411
412/**
413 * Task to be executed when flushing our local buffer takes longer than timeout
414 * given to GNUNET_TESTBED_LOGGER_flush(). The flush completion callback will
415 * be called with 0 as the amount of data sent.
416 *
417 * @param cls the logger handle
418 */
419static void
420timeout_flush (void *cls)
421{
422 struct GNUNET_TESTBED_LOGGER_Handle *h = cls;
423 GNUNET_TESTBED_LOGGER_FlushCompletion cb;
424 void *cb_cls;
425
426 h->timeout_flush_task = NULL;
427 cb = h->cb;
428 h->cb = NULL;
429 cb_cls = h->cb_cls;
430 h->cb_cls = NULL;
431 if (NULL != h->flush_completion_task)
432 {
433 GNUNET_SCHEDULER_cancel (h->flush_completion_task);
434 h->flush_completion_task = NULL;
435 }
436 if (NULL != cb)
437 cb (cb_cls, 0);
438}
439
440
441/**
442 * Flush the buffered data to the logger service
443 *
444 * @param h the logger handle
445 * @param timeout how long to wait before calling the flust completion callback
446 * @param cb the callback to call after the data is flushed
447 * @param cb_cls the closure for the above callback
448 */
449void
450GNUNET_TESTBED_LOGGER_flush (struct GNUNET_TESTBED_LOGGER_Handle *h,
451 struct GNUNET_TIME_Relative timeout,
452 GNUNET_TESTBED_LOGGER_FlushCompletion cb,
453 void *cb_cls)
454{
455 h->cb = cb;
456 h->cb_cls = cb_cls;
457 GNUNET_assert (NULL == h->timeout_flush_task);
458 h->timeout_flush_task =
459 GNUNET_SCHEDULER_add_delayed (timeout, &timeout_flush, h);
460 if (NULL == h->buf)
461 {
462 trigger_flush_notification (h);
463 return;
464 }
465 dispatch_buffer (h);
466}
467
468
469/**
470 * Cancel notification upon flush. Should only be used when the flush
471 * completion callback given to GNUNET_TESTBED_LOGGER_flush() is not already
472 * called.
473 *
474 * @param h the logger handle
475 */
476void
477GNUNET_TESTBED_LOGGER_flush_cancel (struct GNUNET_TESTBED_LOGGER_Handle *h)
478{
479 if (NULL != h->flush_completion_task)
480 {
481 GNUNET_SCHEDULER_cancel (h->flush_completion_task);
482 h->flush_completion_task = NULL;
483 }
484 if (NULL != h->timeout_flush_task)
485 cancel_timeout_flush (h);
486 h->cb = NULL;
487 h->cb_cls = NULL;
488}
489
490/* End of testbed_logger_api.c */