aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2010-07-21 16:56:05 +0000
committerNathan S. Evans <evans@in.tum.de>2010-07-21 16:56:05 +0000
commitafec51a8dd5d9f77a00d902acd7b5efc04675298 (patch)
treea7120c155a29d302d2632708ef77d5cdaef649d0 /src/dht
parentf5e4ff2dd8caeb87907a74ee91846860f7e80707 (diff)
downloadgnunet-afec51a8dd5d9f77a00d902acd7b5efc04675298.tar.gz
gnunet-afec51a8dd5d9f77a00d902acd7b5efc04675298.zip
plugin to write sql queries to file instead of connecting to server
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/plugin_dhtlog_mysql_dump.c545
1 files changed, 545 insertions, 0 deletions
diff --git a/src/dht/plugin_dhtlog_mysql_dump.c b/src/dht/plugin_dhtlog_mysql_dump.c
new file mode 100644
index 000000000..c71f38c87
--- /dev/null
+++ b/src/dht/plugin_dhtlog_mysql_dump.c
@@ -0,0 +1,545 @@
1/*
2 This file is part of GNUnet.
3 (C) 2006 - 2009 Christian Grothoff (and other contributing authors)
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 2, 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., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/dht/plugin_dhtlog_mysql.c
23 * @brief MySQL logging plugin to record DHT operations to MySQL server,
24 * but write all queries to file instead of the actual server
25 * so that they can be imported later. The idea is that connecting
26 * to the MySQL server X times can be really problematic, but hopefully
27 * writing to a single file is more reliable.
28 * @author Nathan Evans
29 *
30 * Database: MySQL
31 */
32
33#include "platform.h"
34#include "gnunet_util_lib.h"
35#include "dhtlog.h"
36
37
38#define DEBUG_DHTLOG GNUNET_NO
39
40/**
41 * Maximum number of supported parameters for a prepared
42 * statement. Increase if needed.
43 */
44#define MAX_PARAM 32
45
46
47static unsigned long max_varchar_len;
48
49/**
50 * The configuration the DHT service is running with
51 */
52static const struct GNUNET_CONFIGURATION_Handle *cfg;
53
54#define INSERT_QUERIES_STMT "prepare insert_query from 'INSERT INTO queries (trialuid, querytype, hops, dhtkeyuid, dhtqueryid, succeeded, nodeuid) "\
55 "VALUES (@temp_trial, ?, ?, ?, ?, ?, ?)'"
56
57#define INSERT_ROUTES_STMT "prepare insert_route from 'INSERT INTO routes (trialuid, querytype, hops, dhtkeyuid, dhtqueryid, succeeded, nodeuid, from_node, to_node) "\
58 "VALUES (@temp_trial, ?, ?, ?, ?, ?, ?, ?, ?)'"
59
60#define INSERT_NODES_STMT "prepare insert_node from 'INSERT INTO nodes (trialuid, nodeid) "\
61 "VALUES (@temp_trial, ?)'"
62
63#define INSERT_TRIALS_STMT "prepare insert_trial from 'INSERT INTO trials"\
64 "(starttime, numnodes, topology,"\
65 "topology_percentage, topology_probability,"\
66 "blacklist_topology, connect_topology, connect_topology_option,"\
67 "connect_topology_option_modifier, puts, gets, "\
68 "concurrent, settle_time, num_rounds, malicious_getters,"\
69 "malicious_putters, malicious_droppers, message) "\
70 "VALUES (NOW(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'"
71
72#define INSERT_DHTKEY_STMT "prepare insert_dhtkey from 'INSERT ignore INTO dhtkeys (dhtkey, trialuid) "\
73 "VALUES (?, @temp_trial)'"
74
75#define UPDATE_TRIALS_STMT "prepare update_trial from 'UPDATE trials set endtime=NOW(), total_messages_dropped = ?, total_bytes_dropped = ?, unknownPeers = ? where trialuid = @temp_trial'"
76
77#define UPDATE_CONNECTIONS_STMT "prepare update_conn from 'UPDATE trials set totalConnections = ? where trialuid = @temp_trial'"
78
79#define GET_TRIAL_STMT "prepare select_trial from 'SELECT MAX( trialuid ) FROM trials into @temp_trial'"
80
81#define GET_DHTKEYUID_STMT "prepare get_dhtkeyuid from 'SELECT dhtkeyuid FROM dhtkeys where dhtkey = ? and trialuid = @temp_trial'"
82
83#define GET_NODEUID_STMT "prepare get_nodeuid from 'SELECT nodeuid FROM nodes where trialuid = @temp_trial and nodeid = ?'"
84
85/**
86 * File to dump all sql statements to.
87 */
88FILE *outfile;
89
90/**
91 * Create a prepared statement.
92 *
93 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
94 */
95static int
96prepared_statement_create (const char *statement)
97{
98 if (fprintf(outfile, "%s;\n", statement) > 0)
99 return GNUNET_OK;
100
101 return GNUNET_SYSERR;
102}
103
104/*
105 * Initialize the prepared statements for use with dht test logging
106 */
107static int
108iopen ()
109{
110#define PINIT(a) (GNUNET_OK != (prepared_statement_create(a)))
111 if (PINIT (INSERT_QUERIES_STMT) ||
112 PINIT (INSERT_ROUTES_STMT) ||
113 PINIT (INSERT_TRIALS_STMT) ||
114 PINIT (INSERT_NODES_STMT) ||
115 PINIT (INSERT_DHTKEY_STMT) ||
116 PINIT (UPDATE_TRIALS_STMT) ||
117 PINIT (GET_DHTKEYUID_STMT) ||
118 PINIT (GET_NODEUID_STMT) ||
119 PINIT (UPDATE_CONNECTIONS_STMT) ||
120 PINIT (GET_TRIAL_STMT))
121 {
122 return GNUNET_SYSERR;
123 }
124#undef PINIT
125 return GNUNET_OK;
126}
127
128
129/*
130 * Inserts the specified trial into the dhttests.trials table
131 *
132 * @param trialuid return the trialuid of the newly inserted trial
133 * @param num_nodes how many nodes are in the trial
134 * @param topology integer representing topology for this trial
135 * @param blacklist_topology integer representing blacklist topology for this trial
136 * @param connect_topology integer representing connect topology for this trial
137 * @param connect_topology_option integer representing connect topology option
138 * @param connect_topology_option_modifier float to modify connect option
139 * @param topology_percentage percentage modifier for certain topologies
140 * @param topology_probability probability modifier for certain topologies
141 * @param puts number of puts to perform
142 * @param gets number of gets to perform
143 * @param concurrent number of concurrent requests
144 * @param settle_time time to wait between creating topology and starting testing
145 * @param num_rounds number of times to repeat the trial
146 * @param malicious_getters number of malicious GET peers in the trial
147 * @param malicious_putters number of malicious PUT peers in the trial
148 * @param malicious_droppers number of malicious DROP peers in the trial
149 * @param message string to put into DB for this trial
150 *
151 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
152 */
153int
154add_trial (unsigned long long *trialuid, int num_nodes, int topology,
155 int blacklist_topology, int connect_topology,
156 int connect_topology_option, float connect_topology_option_modifier,
157 float topology_percentage, float topology_probability,
158 int puts, int gets, int concurrent, int settle_time,
159 int num_rounds, int malicious_getters, int malicious_putters,
160 int malicious_droppers, char *message)
161{
162 int ret;
163 *trialuid = 0;
164 if (outfile == NULL)
165 return GNUNET_SYSERR;
166
167 ret = fprintf(outfile, "set @num = %d, @topology = %d, @bl = %d, "
168 "@connect = %d, @c_t_o = %d, @c_t_o_m = %f, @t_p = %f, "
169 "@t_pr = %f, @puts = %d, @gets = %d, "
170 "@concurrent = %d, @settle = %d, @rounds = %d, "
171 "@m_gets = %d, @m_puts = %d, @m_drops = %d, "
172 "@message = \"%s\";\n", num_nodes, topology,
173 blacklist_topology, connect_topology,
174 connect_topology_option, connect_topology_option_modifier,
175 topology_percentage, topology_probability,
176 puts, gets, concurrent, settle_time,
177 num_rounds, malicious_getters, malicious_putters,
178 malicious_droppers, message);
179
180 if (ret < 0)
181 return GNUNET_SYSERR;
182 ret = fprintf(outfile, "execute insert_trial using "
183 "@num, @topology, @bl, "
184 "@connect, @c_t_o, @c_t_o_m, @t_p, "
185 "@t_pr, @puts, @gets, "
186 "@concurrent, @settle, @rounds, "
187 "@m_gets, @m_puts, @m_drops, "
188 "@message;\n");
189
190 ret = fprintf(outfile, "execute select_trial;\n");
191
192 if (ret >= 0)
193 return GNUNET_OK;
194 return GNUNET_SYSERR;
195}
196
197
198/*
199 * Inserts the specified dhtkey into the dhttests.dhtkeys table,
200 * stores return value of dhttests.dhtkeys.dhtkeyuid into dhtkeyuid
201 *
202 * @param dhtkeyuid return value
203 * @param dhtkey hashcode of key to insert
204 *
205 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
206 */
207int
208add_dhtkey (unsigned long long *dhtkeyuid, const GNUNET_HashCode * dhtkey)
209{
210 int ret;
211 *dhtkeyuid = 0;
212
213 if (outfile == NULL)
214 return GNUNET_SYSERR;
215
216 if (dhtkey != NULL)
217 ret = fprintf(outfile, "set @dhtkey = \"%s\";\n", GNUNET_h2s_full(dhtkey));
218 else
219 ret = fprintf(outfile, "set @dhtkey = XXXXX;\n");
220
221 if (ret < 0)
222 return GNUNET_SYSERR;
223 ret = fprintf(outfile, "execute insert_dhtkey using @dhtkey;\n");
224
225 if (ret >= 0)
226 return GNUNET_OK;
227 return GNUNET_SYSERR;
228}
229
230/*
231 * Inserts the specified node into the dhttests.nodes table
232 *
233 * @param nodeuid the inserted node uid
234 * @param node the node to insert
235 *
236 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
237 */
238int
239add_node (unsigned long long *nodeuid, struct GNUNET_PeerIdentity * node)
240{
241 int ret;
242
243 if (node == NULL)
244 return GNUNET_SYSERR;
245
246 if (outfile == NULL)
247 return GNUNET_SYSERR;
248
249 if (node != NULL)
250 ret = fprintf(outfile, "set @node = \"%s\";\n", GNUNET_h2s_full(&node->hashPubKey));
251 else
252 return GNUNET_SYSERR;
253
254 if (ret < 0)
255 return GNUNET_SYSERR;
256
257 ret = fprintf(outfile, "execute insert_node using @node;\n");
258
259 if (ret >= 0)
260 return GNUNET_OK;
261 return GNUNET_SYSERR;
262}
263
264/*
265 * Update dhttests.trials table with current server time as end time
266 *
267 * @param trialuid trial to update
268 * @param totalMessagesDropped stats value for messages dropped
269 * @param totalBytesDropped stats value for total bytes dropped
270 * @param unknownPeers stats value for unknown peers
271 *
272 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
273 */
274int
275update_trials (unsigned long long trialuid,
276 unsigned long long totalMessagesDropped,
277 unsigned long long totalBytesDropped,
278 unsigned long long unknownPeers)
279{
280 int ret;
281#if DEBUG_DHTLOG
282 if (trialuid != current_trial)
283 {
284 fprintf (stderr,
285 _("Trialuid to update is not equal to current_trial\n"));
286 }
287#endif
288
289 if (outfile == NULL)
290 return GNUNET_SYSERR;
291
292 ret = fprintf(outfile, "set @m_dropped = %llu, @b_dropped = %llu, @unknown = %llu;\n", totalMessagesDropped, totalBytesDropped, unknownPeers);
293
294 if (ret < 0)
295 return GNUNET_SYSERR;
296
297 ret = fprintf(outfile, "execute update_trial using @m_dropped, @b_dropped, @unknown;\n");
298
299 if (ret >= 0)
300 return GNUNET_OK;
301 else
302 return GNUNET_SYSERR;
303}
304
305
306/*
307 * Update dhttests.trials table with total connections information
308 *
309 * @param trialuid the trialuid to update
310 * @param totalConnections the number of connections
311 *
312 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
313 */
314int
315add_connections (unsigned long long trialuid, unsigned int totalConnections)
316{
317 int ret;
318#if DEBUG_DHTLOG
319 if (trialuid != current_trial)
320 {
321 fprintf (stderr,
322 _("Trialuid to update is not equal to current_trial(!)(?)\n"));
323 }
324#endif
325 if (outfile == NULL)
326 return GNUNET_SYSERR;
327
328 ret = fprintf(outfile, "set @conns = %u;\n", totalConnections);
329
330 if (ret < 0)
331 return GNUNET_SYSERR;
332
333 ret = fprintf(outfile, "execute update_connections using @conns;\n");
334
335 if (ret >= 0)
336 return GNUNET_OK;
337 else
338 return GNUNET_SYSERR;
339}
340
341/*
342 * Inserts the specified query into the dhttests.queries table
343 *
344 * @param sqlqueruid inserted query uid
345 * @param queryid dht query id
346 * @param type type of the query
347 * @param hops number of hops query traveled
348 * @param succeeded whether or not query was successful
349 * @param node the node the query hit
350 * @param key the key of the query
351 *
352 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
353 */
354int
355add_query (unsigned long long *sqlqueryuid, unsigned long long queryid,
356 unsigned int type, unsigned int hops, int succeeded,
357 const struct GNUNET_PeerIdentity * node, const GNUNET_HashCode * key)
358{
359 int ret;
360
361 if (outfile == NULL)
362 return GNUNET_SYSERR;
363
364 *sqlqueryuid = 0;
365
366 if (key != NULL)
367 ret = fprintf(outfile, "select dhtkeyuid from dhtkeys where trialuid = @temp_trial and dhtkey = \"%s\" into @temp_dhtkey;\n", GNUNET_h2s_full(key));
368 else
369 ret = fprintf(outfile, "set @temp_dhtkey = 0;\n");
370
371 if (node != NULL)
372 ret = fprintf(outfile, "select nodeuid from nodes where trialuid = @temp_trial and nodeid = \"%s\" into @temp_node;\n", GNUNET_h2s_full(&node->hashPubKey));
373 else
374 ret = fprintf(outfile, "set @temp_node = 0;\n");
375
376 ret = fprintf(outfile, "set @qid = %llu, @type = %u, @hops = %u, @succ = %d;\n", queryid, type, hops, succeeded);
377
378 if (ret < 0)
379 return GNUNET_SYSERR;
380
381 ret = fprintf(outfile, "execute insert_query using @type, @hops, @temp_dhtkey, @qid, @succ, @temp_node;\n");
382
383 if (ret >= 0)
384 return GNUNET_OK;
385 else
386 return GNUNET_SYSERR;
387}
388
389/*
390 * Inserts the specified route information into the dhttests.routes table
391 *
392 * @param sqlqueruid inserted query uid
393 * @param queryid dht query id
394 * @param type type of the query
395 * @param hops number of hops query traveled
396 * @param succeeded whether or not query was successful
397 * @param node the node the query hit
398 * @param key the key of the query
399 * @param from_node the node that sent the message to node
400 * @param to_node next node to forward message to
401 *
402 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
403 */
404int
405add_route (unsigned long long *sqlqueryuid, unsigned long long queryid,
406 unsigned int type, unsigned int hops,
407 int succeeded, const struct GNUNET_PeerIdentity * node,
408 const GNUNET_HashCode * key, const struct GNUNET_PeerIdentity * from_node,
409 const struct GNUNET_PeerIdentity * to_node)
410{
411 int ret;
412
413 if (outfile == NULL)
414 return GNUNET_SYSERR;
415
416 *sqlqueryuid = 0;
417
418 if (key != NULL)
419 ret = fprintf(outfile, "select dhtkeyuid from dhtkeys where trialuid = @temp_trial and dhtkey = \"%s\" into @temp_dhtkey;\n", GNUNET_h2s_full(key));
420 else
421 ret = fprintf(outfile, "set @temp_dhtkey = 0;\n");
422
423 if (node != NULL)
424 ret = fprintf(outfile, "select nodeuid from nodes where trialuid = @temp_trial and nodeid = \"%s\" into @temp_node;\n", GNUNET_h2s_full(&node->hashPubKey));
425 else
426 ret = fprintf(outfile, "set @temp_node = 0;\n");
427
428 if (from_node != NULL)
429 ret = fprintf(outfile, "select nodeuid from nodes where trialuid = @temp_trial and nodeid = \"%s\" into @temp_from_node;\n", GNUNET_h2s_full(&from_node->hashPubKey));
430 else
431 ret = fprintf(outfile, "set @temp_from_node = 0;\n");
432
433 if (to_node != NULL)
434 ret = fprintf(outfile, "select nodeuid from nodes where trialuid = @temp_trial and nodeid = \"%s\" into @temp_to_node;\n", GNUNET_h2s_full(&to_node->hashPubKey));
435 else
436 ret = fprintf(outfile, "set @temp_to_node = 0;\n");
437
438 ret = fprintf(outfile, "set @qid = %llu, @type = %u, @hops = %u, @succ = %d;\n", queryid, type, hops, succeeded);
439
440 if (ret < 0)
441 return GNUNET_SYSERR;
442
443 ret = fprintf(outfile, "execute insert_route using @type, @hops, @temp_dhtkey, @qid, @succ, @temp_node, @temp_from_node, @temp_to_node;\n");
444
445 if (ret >= 0)
446 return GNUNET_OK;
447 else
448 return GNUNET_SYSERR;
449}
450
451/*
452 * Provides the dhtlog api
453 *
454 * @param c the configuration to use to connect to a server
455 *
456 * @return the handle to the server, or NULL on error
457 */
458void *
459libgnunet_plugin_dhtlog_mysql_dump_init (void * cls)
460{
461 struct GNUNET_DHTLOG_Plugin *plugin = cls;
462 char *outfile_name;
463 char *outfile_path;
464 char *fn;
465 int dirwarn;
466
467 cfg = plugin->cfg;
468 max_varchar_len = 255;
469
470#if DEBUG_DHTLOG
471 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MySQL (DUMP) DHT Logger: initializing\n");
472#endif
473
474 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
475 "MYSQLDUMP", "PATH",
476 &outfile_path))
477 {
478 outfile_path = GNUNET_strdup("");
479 }
480
481 GNUNET_asprintf (&outfile_name,
482 "%s%s-%d",
483 outfile_path,
484 "mysqldump",
485 getpid());
486
487 fn = GNUNET_STRINGS_filename_expand (outfile_name);
488
489 dirwarn = (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn));
490 outfile = FOPEN (fn, "w");
491
492 if (outfile == NULL)
493 {
494 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
495 if (dirwarn)
496 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
497 _("Failed to create or access directory for log file `%s'\n"),
498 fn);
499 GNUNET_free(outfile_path);
500 GNUNET_free(outfile_name);
501 GNUNET_free (fn);
502 return NULL;
503 }
504
505 GNUNET_free (outfile_path);
506 GNUNET_free (outfile_name);
507 GNUNET_free (fn);
508
509 if (iopen () != GNUNET_OK)
510 {
511 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
512 _("Failed to create file for dhtlog.\n"));
513 return NULL;
514 }
515 GNUNET_assert(plugin->dhtlog_api == NULL);
516 plugin->dhtlog_api = GNUNET_malloc(sizeof(struct GNUNET_DHTLOG_Handle));
517 plugin->dhtlog_api->insert_trial = &add_trial;
518 plugin->dhtlog_api->insert_query = &add_query;
519 plugin->dhtlog_api->update_trial = &update_trials;
520 plugin->dhtlog_api->insert_route = &add_route;
521 plugin->dhtlog_api->insert_node = &add_node;
522 plugin->dhtlog_api->insert_dhtkey = &add_dhtkey;
523 plugin->dhtlog_api->update_connections = &add_connections;
524
525 return NULL;
526}
527
528/**
529 * Shutdown the plugin.
530 */
531void *
532libgnunet_plugin_dhtlog_mysql_dump_done (void * cls)
533{
534 struct GNUNET_DHTLOG_Handle *dhtlog_api = cls;
535#if DEBUG_DHTLOG
536 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
537 "MySQL DHT Logger: database shutdown\n");
538#endif
539 GNUNET_assert(dhtlog_api != NULL);
540
541 GNUNET_free(dhtlog_api);
542 return NULL;
543}
544
545/* end of plugin_dhtlog_mysql.c */