2 This file is part of GNUnet.
3 (C) 2006 - 2009 Christian Grothoff (and other contributing authors)
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.
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.
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.
22 * @file src/dht/plugin_dhtlog_mysql.c
23 * @brief MySQL logging plugin to record DHT operations to MySQL server
24 * @author Nathan Evans
30 #include "gnunet_util_lib.h"
32 #include <mysql/mysql.h>
35 #define DEBUG_DHTLOG GNUNET_YES
38 * Maximum number of supported parameters for a prepared
39 * statement. Increase if needed.
44 * A generic statement handle to use
45 * for prepared statements. This way,
46 * once the statement is initialized
49 struct StatementHandle
54 MYSQL_STMT *statement;
62 * Whether or not the handle is valid
68 * Type of a callback that will be called for each
69 * data set returned from MySQL.
71 * @param cls user-defined argument
72 * @param num_values number of elements in values
73 * @param values values returned by MySQL
74 * @return GNUNET_OK to continue iterating, GNUNET_SYSERR to abort
76 typedef int (*GNUNET_MysqlDataProcessor) (void *cls,
77 unsigned int num_values,
80 static unsigned long max_varchar_len;
83 * The configuration the DHT service is running with
85 static const struct GNUNET_CONFIGURATION_Handle *cfg;
87 static unsigned long long current_trial = 0; /* I like to assign 0, just to remember */
90 * Connection to the MySQL Server.
94 #define INSERT_QUERIES_STMT "INSERT INTO queries (trialuid, querytype, hops, dhtkeyuid, dhtqueryid, succeeded, nodeuid, time) "\
95 "VALUES (?, ?, ?, ?, ?, ?, ?, NOW())"
96 static struct StatementHandle *insert_query;
98 #define INSERT_ROUTES_STMT "INSERT INTO routes (trialuid, querytype, hops, dhtkeyuid, dhtqueryid, succeeded, nodeuid, from_node, to_node) "\
99 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
100 static struct StatementHandle *insert_route;
102 #define INSERT_NODES_STMT "INSERT INTO nodes (trialuid, nodeid, nodebits) "\
104 static struct StatementHandle *insert_node;
106 #define INSERT_ROUNDS_STMT "INSERT INTO rounds (trialuid, round_type, round_count, starttime) "\
107 "VALUES (?, ?, ?, NOW())"
109 static struct StatementHandle *insert_round;
111 #define INSERT_TRIALS_STMT "INSERT INTO trials"\
112 "(starttime, other_trial_identifier, numnodes, topology,"\
113 "topology_percentage, topology_probability,"\
114 "blacklist_topology, connect_topology, connect_topology_option,"\
115 "connect_topology_option_modifier, puts, gets, "\
116 "concurrent, settle_time, num_rounds, malicious_getters,"\
117 "malicious_putters, malicious_droppers, malicious_get_frequency,"\
118 "malicious_put_frequency, stop_closest, stop_found, strict_kademlia, "\
119 "gets_succeeded, message) "\
120 "VALUES (NOW(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
122 static struct StatementHandle *insert_trial;
124 #define INSERT_STAT_STMT "INSERT INTO node_statistics"\
125 "(trialuid, nodeuid, route_requests,"\
126 "route_forwards, result_requests,"\
127 "client_results, result_forwards, gets,"\
128 "puts, data_inserts, find_peer_requests, "\
129 "find_peers_started, gets_started, puts_started, find_peer_responses_received,"\
130 "get_responses_received, find_peer_responses_sent, get_responses_sent) "\
131 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
133 static struct StatementHandle *insert_stat;
135 #define INSERT_GENERIC_STAT_STMT "INSERT INTO generic_stats" \
136 "(trialuid, nodeuid, section, name, value)"\
137 "VALUES (?, ?, ?, ?, ?)"
138 static struct StatementHandle *insert_generic_stat;
140 #define INSERT_DHTKEY_STMT "INSERT INTO dhtkeys (dhtkey, trialuid, keybits) "\
142 static struct StatementHandle *insert_dhtkey;
144 #define UPDATE_TRIALS_STMT "UPDATE trials set endtime=NOW(), gets_succeeded = ? where trialuid = ?"
145 static struct StatementHandle *update_trial;
147 #define UPDATE_CONNECTIONS_STMT "UPDATE trials set totalConnections = ? where trialuid = ?"
148 static struct StatementHandle *update_connection;
150 #define GET_TRIAL_STMT "SELECT MAX( trialuid ) FROM trials"
151 static struct StatementHandle *get_trial;
153 #define GET_TOPOLOGY_STMT "SELECT MAX( topology_uid ) FROM topology"
154 static struct StatementHandle *get_topology;
156 #define GET_DHTKEYUID_STMT "SELECT dhtkeyuid FROM dhtkeys where dhtkey = ? and trialuid = ?"
157 static struct StatementHandle *get_dhtkeyuid;
159 #define GET_NODEUID_STMT "SELECT nodeuid FROM nodes where trialuid = ? and nodeid = ?"
160 static struct StatementHandle *get_nodeuid;
162 #define INSERT_TOPOLOGY_STMT "INSERT INTO topology (trialuid, date, connections) "\
163 "VALUES (?, NOW(), ?)"
164 static struct StatementHandle *insert_topology;
166 #define EXTEND_TOPOLOGY_STMT "INSERT INTO extended_topology (topology_uid, uid_first, uid_second) "\
168 static struct StatementHandle *extend_topology;
170 #define SET_MALICIOUS_STMT "update nodes set malicious_dropper = 1 where trialuid = ? and nodeid = ?"
171 static struct StatementHandle *update_node_malicious;
173 #define UPDATE_TOPOLOGY_STMT "update topology set connections = ? where topology_uid = ?"
174 static struct StatementHandle *update_topology;
177 * Run a query (not a select statement)
179 * @return GNUNET_OK if executed, GNUNET_SYSERR if an error occurred
182 run_statement (const char *statement)
184 mysql_query (conn, statement);
185 if (mysql_error (conn)[0])
187 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
189 return GNUNET_SYSERR;
195 * Creates tables if they don't already exist for dht logging
200 #define MRUNS(a) (GNUNET_OK != run_statement (a) )
202 if (MRUNS ("CREATE TABLE IF NOT EXISTS `dhtkeys` ("
203 "dhtkeyuid int(10) unsigned NOT NULL auto_increment COMMENT 'Unique Key given to each query',"
204 "`dhtkey` varchar(255) NOT NULL COMMENT 'The ASCII value of the key being searched for',"
205 "trialuid int(10) unsigned NOT NULL,"
206 "keybits blob NOT NULL,"
207 "UNIQUE KEY `dhtkeyuid` (`dhtkeyuid`)"
208 ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
209 return GNUNET_SYSERR;
211 if (MRUNS ("CREATE TABLE IF NOT EXISTS `nodes` ("
212 "`nodeuid` int(10) unsigned NOT NULL auto_increment,"
213 "`trialuid` int(10) unsigned NOT NULL,"
214 "`nodeid` varchar(255) NOT NULL,"
215 "`nodebits` blob NOT NULL,"
216 "PRIMARY KEY (`nodeuid`)"
217 ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
218 return GNUNET_SYSERR;
220 if (MRUNS ("CREATE TABLE IF NOT EXISTS `queries` ("
221 "`trialuid` int(10) unsigned NOT NULL,"
222 "`queryuid` int(10) unsigned NOT NULL auto_increment,"
223 "`dhtqueryid` bigint(20) NOT NULL,"
224 "`querytype` enum('1','2','3','4','5') NOT NULL,"
225 "`hops` int(10) unsigned NOT NULL,"
226 "`succeeded` tinyint NOT NULL,"
227 "`nodeuid` int(10) unsigned NOT NULL,"
228 "`time` timestamp NOT NULL default CURRENT_TIMESTAMP,"
229 "`dhtkeyuid` int(10) unsigned NOT NULL,"
230 "PRIMARY KEY (`queryuid`)"
231 ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
232 return GNUNET_SYSERR;
234 if (MRUNS ("CREATE TABLE IF NOT EXISTS `routes` ("
235 "`trialuid` int(10) unsigned NOT NULL,"
236 "`queryuid` int(10) unsigned NOT NULL auto_increment,"
237 "`dhtqueryid` bigint(20) NOT NULL,"
238 "`querytype` enum('1','2','3','4','5') NOT NULL,"
239 "`hops` int(10) unsigned NOT NULL,"
240 "`succeeded` tinyint NOT NULL,"
241 "`nodeuid` int(10) unsigned NOT NULL,"
242 "`time` timestamp NOT NULL default CURRENT_TIMESTAMP,"
243 "`dhtkeyuid` int(10) unsigned NOT NULL,"
244 "`from_node` int(10) unsigned NOT NULL,"
245 "`to_node` int(10) unsigned NOT NULL,"
246 "PRIMARY KEY (`queryuid`)"
247 ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
248 return GNUNET_SYSERR;
250 if (MRUNS ("CREATE TABLE IF NOT EXISTS `trials` ("
251 "`trialuid` int(10) unsigned NOT NULL auto_increment,"
252 "`other_trial_identifier` int(10) unsigned NOT NULL default '0',"
253 "`numnodes` int(10) unsigned NOT NULL,"
254 "`topology` int(10) NOT NULL,"
255 "`blacklist_topology` int(11) NOT NULL,"
256 "`connect_topology` int(11) NOT NULL,"
257 "`connect_topology_option` int(11) NOT NULL,"
258 "`topology_percentage` float NOT NULL,"
259 "`topology_probability` float NOT NULL,"
260 "`connect_topology_option_modifier` float NOT NULL,"
261 "`starttime` datetime NOT NULL,"
262 "`endtime` datetime NOT NULL,"
263 "`puts` int(10) unsigned NOT NULL,"
264 "`gets` int(10) unsigned NOT NULL,"
265 "`concurrent` int(10) unsigned NOT NULL,"
266 "`settle_time` int(10) unsigned NOT NULL,"
267 "`totalConnections` int(10) unsigned NOT NULL,"
268 "`message` text NOT NULL,"
269 "`num_rounds` int(10) unsigned NOT NULL,"
270 "`malicious_getters` int(10) unsigned NOT NULL,"
271 "`malicious_putters` int(10) unsigned NOT NULL,"
272 "`malicious_droppers` int(10) unsigned NOT NULL,"
273 "`topology_modifier` double NOT NULL,"
274 "`malicious_get_frequency` int(10) unsigned NOT NULL,"
275 "`malicious_put_frequency` int(10) unsigned NOT NULL,"
276 "`stop_closest` int(10) unsigned NOT NULL,"
277 "`stop_found` int(10) unsigned NOT NULL,"
278 "`strict_kademlia` int(10) unsigned NOT NULL,"
279 "`gets_succeeded` int(10) unsigned NOT NULL,"
280 "PRIMARY KEY (`trialuid`),"
281 "UNIQUE KEY `trialuid` (`trialuid`)"
282 ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
283 return GNUNET_SYSERR;
285 if (MRUNS ("CREATE TABLE IF NOT EXISTS `topology` ("
286 "`topology_uid` int(10) unsigned NOT NULL AUTO_INCREMENT,"
287 "`trialuid` int(10) unsigned NOT NULL,"
288 "`date` datetime NOT NULL,"
289 "`connections` int(10) unsigned NOT NULL,"
290 "PRIMARY KEY (`topology_uid`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
291 return GNUNET_SYSERR;
293 if (MRUNS ("CREATE TABLE IF NOT EXISTS `extended_topology` ("
294 "`extended_uid` int(10) unsigned NOT NULL AUTO_INCREMENT,"
295 "`topology_uid` int(10) unsigned NOT NULL,"
296 "`uid_first` int(10) unsigned NOT NULL,"
297 "`uid_second` int(10) unsigned NOT NULL,"
298 "PRIMARY KEY (`extended_uid`)"
299 ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
300 return GNUNET_SYSERR;
302 if (MRUNS ("CREATE TABLE IF NOT EXISTS `node_statistics` ("
303 "`stat_uid` int(10) unsigned NOT NULL AUTO_INCREMENT,"
304 "`trialuid` int(10) unsigned NOT NULL,"
305 "`nodeuid` int(10) unsigned NOT NULL,"
306 "`route_requests` int(10) unsigned NOT NULL,"
307 "`route_forwards` int(10) unsigned NOT NULL,"
308 "`result_requests` int(10) unsigned NOT NULL,"
309 "`client_results` int(10) unsigned NOT NULL,"
310 "`result_forwards` int(10) unsigned NOT NULL,"
311 "`gets` int(10) unsigned NOT NULL,"
312 "`puts` int(10) unsigned NOT NULL,"
313 "`data_inserts` int(10) unsigned NOT NULL,"
314 "`find_peer_requests` int(10) unsigned NOT NULL,"
315 "`find_peers_started` int(10) unsigned NOT NULL,"
316 "`gets_started` int(10) unsigned NOT NULL,"
317 "`puts_started` int(10) unsigned NOT NULL,"
318 "`find_peer_responses_received` int(10) unsigned NOT NULL,"
319 "`get_responses_received` int(10) unsigned NOT NULL,"
320 "`find_peer_responses_sent` int(10) unsigned NOT NULL,"
321 "`get_responses_sent` int(10) unsigned NOT NULL,"
322 "PRIMARY KEY (`stat_uid`)"
323 ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;"))
324 return GNUNET_SYSERR;
326 if (MRUNS ("SET AUTOCOMMIT = 1"))
327 return GNUNET_SYSERR;
334 * Create a prepared statement.
336 * @return NULL on error
338 struct StatementHandle *
339 prepared_statement_create (const char *statement)
341 struct StatementHandle *ret;
343 ret = GNUNET_malloc (sizeof (struct StatementHandle));
344 ret->query = GNUNET_strdup (statement);
349 * Close a prepared statement.
351 * @return NULL on error
354 prepared_statement_close (struct StatementHandle *s)
361 GNUNET_free_non_null(s->query);
363 if (s->valid == GNUNET_YES)
364 mysql_stmt_close(s->statement);
369 * Initialize the prepared statements for use with dht test logging
372 iopen (struct GNUNET_DHTLOG_Plugin *plugin)
376 unsigned int timeout;
381 unsigned long long port;
383 conn = mysql_init (NULL);
385 return GNUNET_SYSERR;
387 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
391 database = GNUNET_strdup("gnunet");
394 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
395 "MYSQL", "USER", &user))
397 user = GNUNET_strdup("dht");
400 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
401 "MYSQL", "PASSWORD", &password))
403 password = GNUNET_strdup("dhttest**");
406 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
407 "MYSQL", "SERVER", &server))
409 server = GNUNET_strdup("localhost");
412 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (plugin->cfg,
413 "MYSQL", "MYSQL_PORT", &port))
418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to mysql with: user %s, pass %s, server %s, database %s, port %d\n",
419 user, password, server, database, port);
422 timeout = 60; /* in seconds */
423 mysql_options (conn, MYSQL_OPT_RECONNECT, &reconnect);
425 MYSQL_OPT_CONNECT_TIMEOUT, (const void *) &timeout);
426 mysql_options(conn, MYSQL_SET_CHARSET_NAME, "UTF8");
427 mysql_options (conn, MYSQL_OPT_READ_TIMEOUT, (const void *) &timeout);
428 mysql_options (conn, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout);
429 mysql_real_connect (conn, server, user, password,
430 database, (unsigned int) port, NULL, CLIENT_IGNORE_SIGPIPE);
432 GNUNET_free_non_null(server);
433 GNUNET_free_non_null(password);
434 GNUNET_free_non_null(user);
435 GNUNET_free_non_null(database);
437 if (mysql_error (conn)[0])
439 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
440 "mysql_real_connect");
441 return GNUNET_SYSERR;
445 db = GNUNET_MYSQL_database_open (coreAPI->ectx, coreAPI->cfg);
447 return GNUNET_SYSERR;
452 #define PINIT(a,b) (NULL == (a = prepared_statement_create(b)))
453 if (PINIT (insert_query, INSERT_QUERIES_STMT) ||
454 PINIT (insert_route, INSERT_ROUTES_STMT) ||
455 PINIT (insert_trial, INSERT_TRIALS_STMT) ||
456 PINIT (insert_round, INSERT_ROUNDS_STMT) ||
457 PINIT (insert_stat, INSERT_STAT_STMT) ||
458 PINIT (insert_generic_stat, INSERT_GENERIC_STAT_STMT) ||
459 PINIT (insert_node, INSERT_NODES_STMT) ||
460 PINIT (insert_dhtkey, INSERT_DHTKEY_STMT) ||
461 PINIT (update_trial, UPDATE_TRIALS_STMT) ||
462 PINIT (get_dhtkeyuid, GET_DHTKEYUID_STMT) ||
463 PINIT (get_nodeuid, GET_NODEUID_STMT) ||
464 PINIT (update_connection, UPDATE_CONNECTIONS_STMT) ||
465 PINIT (get_trial, GET_TRIAL_STMT) ||
466 PINIT (get_topology, GET_TOPOLOGY_STMT) ||
467 PINIT (insert_topology, INSERT_TOPOLOGY_STMT) ||
468 PINIT (update_topology, UPDATE_TOPOLOGY_STMT) ||
469 PINIT (extend_topology, EXTEND_TOPOLOGY_STMT) ||
470 PINIT (update_node_malicious, SET_MALICIOUS_STMT) )
472 return GNUNET_SYSERR;
480 return_ok (void *cls, unsigned int num_values, MYSQL_BIND * values)
486 * Prepare a statement for running.
488 * @return GNUNET_OK on success
491 prepare_statement (struct StatementHandle *ret)
493 if (GNUNET_YES == ret->valid)
496 ret->statement = mysql_stmt_init (conn);
497 if (ret->statement == NULL)
498 return GNUNET_SYSERR;
500 if (mysql_stmt_prepare (ret->statement, ret->query, strlen (ret->query)))
502 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
503 "mysql_stmt_prepare `%s', %s", ret->query, mysql_error(conn));
504 mysql_stmt_close (ret->statement);
505 ret->statement = NULL;
506 return GNUNET_SYSERR;
508 ret->valid = GNUNET_YES;
513 * Bind the parameters for the given MySQL statement
516 * @param s statement to bind and run
517 * @param ap arguments for the binding
518 * @return GNUNET_SYSERR on error, GNUNET_OK on success
521 init_params (struct StatementHandle *s, va_list ap)
523 MYSQL_BIND qbind[MAX_PARAM];
526 enum enum_field_types ft;
528 pc = mysql_stmt_param_count (s->statement);
531 /* increase internal constant! */
533 return GNUNET_SYSERR;
535 memset (qbind, 0, sizeof (qbind));
538 while ((pc > 0) && (-1 != (ft = va_arg (ap, enum enum_field_types))))
540 qbind[off].buffer_type = ft;
543 case MYSQL_TYPE_FLOAT:
544 qbind[off].buffer = va_arg (ap, float *);
546 case MYSQL_TYPE_LONGLONG:
547 qbind[off].buffer = va_arg (ap, unsigned long long *);
548 qbind[off].is_unsigned = va_arg (ap, int);
550 case MYSQL_TYPE_LONG:
551 qbind[off].buffer = va_arg (ap, unsigned int *);
552 qbind[off].is_unsigned = va_arg (ap, int);
554 case MYSQL_TYPE_VAR_STRING:
555 case MYSQL_TYPE_STRING:
556 case MYSQL_TYPE_BLOB:
557 qbind[off].buffer = va_arg (ap, void *);
558 qbind[off].buffer_length = va_arg (ap, unsigned long);
559 qbind[off].length = va_arg (ap, unsigned long *);
562 /* unsupported type */
564 return GNUNET_SYSERR;
569 if (!((pc == 0) && (ft != -1) && (va_arg (ap, int) == -1)))
572 return GNUNET_SYSERR;
574 if (mysql_stmt_bind_param (s->statement, qbind))
576 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
577 _("`%s' failed at %s:%d with error: %s\n"),
578 "mysql_stmt_bind_param",
579 __FILE__, __LINE__, mysql_stmt_error (s->statement));
580 return GNUNET_SYSERR;
583 if (mysql_stmt_execute (s->statement))
585 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
586 _("`%s' failed at %s:%d with error: %s\n"),
587 "mysql_stmt_execute",
588 __FILE__, __LINE__, mysql_stmt_error (s->statement));
589 return GNUNET_SYSERR;
596 * Run a prepared SELECT statement.
598 * @param s handle to the statement we should execute
599 * @param result_size number of results in set
600 * @param results pointer to already initialized MYSQL_BIND
601 * array (of sufficient size) for passing results
602 * @param processor function to call on each result
603 * @param processor_cls extra argument to processor
604 * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective
605 * values (size + buffer-reference for pointers); terminated
608 * @return GNUNET_SYSERR on error, otherwise
609 * the number of successfully affected (or queried) rows
612 prepared_statement_run_select (struct StatementHandle *s,
613 unsigned int result_size,
614 MYSQL_BIND * results,
615 GNUNET_MysqlDataProcessor
616 processor, void *processor_cls,
624 if (GNUNET_OK != prepare_statement (s))
627 return GNUNET_SYSERR;
629 va_start (ap, processor_cls);
630 if (GNUNET_OK != init_params (s, ap))
634 return GNUNET_SYSERR;
637 rsize = mysql_stmt_field_count (s->statement);
638 if (rsize > result_size)
641 return GNUNET_SYSERR;
643 if (mysql_stmt_bind_result (s->statement, results))
645 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
646 _("`%s' failed at %s:%d with error: %s\n"),
647 "mysql_stmt_bind_result",
648 __FILE__, __LINE__, mysql_stmt_error (s->statement));
649 return GNUNET_SYSERR;
655 ret = mysql_stmt_fetch (s->statement);
656 if (ret == MYSQL_NO_DATA)
660 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
661 _("`%s' failed at %s:%d with error: %s\n"),
663 __FILE__, __LINE__, mysql_stmt_error (s->statement));
664 return GNUNET_SYSERR;
666 if (processor != NULL)
667 if (GNUNET_OK != processor (processor_cls, rsize, results))
671 mysql_stmt_reset (s->statement);
677 get_node_uid (unsigned long long *nodeuid, const GNUNET_HashCode * peerHash)
680 struct GNUNET_CRYPTO_HashAsciiEncoded encPeer;
681 unsigned long long p_len;
684 memset (rbind, 0, sizeof (rbind));
685 rbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
686 rbind[0].buffer = nodeuid;
687 rbind[0].is_unsigned = GNUNET_YES;
689 GNUNET_CRYPTO_hash_to_enc (peerHash, &encPeer);
690 p_len = strlen ((char *) &encPeer);
692 if (1 != (ret = prepared_statement_run_select (get_nodeuid,
700 MYSQL_TYPE_VAR_STRING,
706 fprintf (stderr, "FAILED\n");
708 return GNUNET_SYSERR;
714 get_current_trial (unsigned long long *trialuid)
718 memset (rbind, 0, sizeof (rbind));
719 rbind[0].buffer_type = MYSQL_TYPE_LONG;
720 rbind[0].is_unsigned = 1;
721 rbind[0].buffer = trialuid;
724 prepared_statement_run_select (get_trial,
727 return_ok, NULL, -1)))
729 return GNUNET_SYSERR;
736 get_current_topology (unsigned long long *topologyuid)
740 memset (rbind, 0, sizeof (rbind));
741 rbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
742 rbind[0].is_unsigned = 1;
743 rbind[0].buffer = topologyuid;
746 prepared_statement_run_select (get_topology,
749 return_ok, NULL, -1)))
751 return GNUNET_SYSERR;
758 get_dhtkey_uid (unsigned long long *dhtkeyuid, const GNUNET_HashCode * key)
761 struct GNUNET_CRYPTO_HashAsciiEncoded encKey;
762 unsigned long long k_len;
763 memset (rbind, 0, sizeof (rbind));
764 rbind[0].buffer_type = MYSQL_TYPE_LONG;
765 rbind[0].is_unsigned = 1;
766 rbind[0].buffer = dhtkeyuid;
767 GNUNET_CRYPTO_hash_to_enc (key, &encKey);
768 k_len = strlen ((char *) &encKey);
770 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Searching for dhtkey `%s' in trial %llu\n", GNUNET_h2s(key), current_trial);
773 prepared_statement_run_select (get_dhtkeyuid,
777 MYSQL_TYPE_VAR_STRING,
785 return GNUNET_SYSERR;
792 * Run a prepared statement that does NOT produce results.
794 * @param s handle to the statement we should execute
795 * @param insert_id NULL or address where to store the row ID of whatever
796 * was inserted (only for INSERT statements!)
797 * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective
798 * values (size + buffer-reference for pointers); terminated
801 * @return GNUNET_SYSERR on error, otherwise
802 * the number of successfully affected rows
805 prepared_statement_run (struct StatementHandle *s,
806 unsigned long long *insert_id, ...)
811 if (GNUNET_OK != prepare_statement(s))
814 return GNUNET_SYSERR;
816 GNUNET_assert(s->valid == GNUNET_YES);
817 if (s->statement == NULL)
818 return GNUNET_SYSERR;
820 va_start (ap, insert_id);
822 if (GNUNET_OK != init_params (s, ap))
825 return GNUNET_SYSERR;
829 affected = mysql_stmt_affected_rows (s->statement);
830 if (NULL != insert_id)
831 *insert_id = (unsigned long long) mysql_stmt_insert_id (s->statement);
832 mysql_stmt_reset (s->statement);
838 * Inserts the specified trial into the dhttests.trials table
840 * @param trial_info struct containing the data to insert about this trial
842 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
844 int add_trial (struct GNUNET_DHTLOG_TrialInfo *trial_info)
848 unsigned long long m_len;
849 m_len = strlen (trial_info->message);
851 stmt = mysql_stmt_init(conn);
853 (ret = prepared_statement_run (insert_trial, &trial_info->trialuid,
854 MYSQL_TYPE_LONG, &trial_info->other_identifier, GNUNET_YES,
855 MYSQL_TYPE_LONG, &trial_info->num_nodes, GNUNET_YES,
856 MYSQL_TYPE_LONG, &trial_info->topology, GNUNET_YES,
857 MYSQL_TYPE_FLOAT, &trial_info->topology_percentage,
858 MYSQL_TYPE_FLOAT, &trial_info->topology_probability,
859 MYSQL_TYPE_LONG, &trial_info->blacklist_topology, GNUNET_YES,
860 MYSQL_TYPE_LONG, &trial_info->connect_topology, GNUNET_YES,
861 MYSQL_TYPE_LONG, &trial_info->connect_topology_option, GNUNET_YES,
862 MYSQL_TYPE_FLOAT, &trial_info->connect_topology_option_modifier,
863 MYSQL_TYPE_LONG, &trial_info->puts, GNUNET_YES,
864 MYSQL_TYPE_LONG, &trial_info->gets, GNUNET_YES,
865 MYSQL_TYPE_LONG, &trial_info->concurrent, GNUNET_YES,
866 MYSQL_TYPE_LONG, &trial_info->settle_time, GNUNET_YES,
867 MYSQL_TYPE_LONG, &trial_info->num_rounds, GNUNET_YES,
868 MYSQL_TYPE_LONG, &trial_info->malicious_getters, GNUNET_YES,
869 MYSQL_TYPE_LONG, &trial_info->malicious_putters, GNUNET_YES,
870 MYSQL_TYPE_LONG, &trial_info->malicious_droppers, GNUNET_YES,
871 MYSQL_TYPE_LONG, &trial_info->malicious_get_frequency, GNUNET_YES,
872 MYSQL_TYPE_LONG, &trial_info->malicious_put_frequency, GNUNET_YES,
873 MYSQL_TYPE_LONG, &trial_info->stop_closest, GNUNET_YES,
874 MYSQL_TYPE_LONG, &trial_info->stop_found, GNUNET_YES,
875 MYSQL_TYPE_LONG, &trial_info->strict_kademlia, GNUNET_YES,
876 MYSQL_TYPE_LONG, &trial_info->gets_succeeded, GNUNET_YES,
877 MYSQL_TYPE_BLOB, trial_info->message, max_varchar_len +
878 max_varchar_len, &m_len,
881 if (ret == GNUNET_SYSERR)
883 mysql_stmt_close(stmt);
884 return GNUNET_SYSERR;
888 get_current_trial (¤t_trial);
890 mysql_stmt_close(stmt);
895 * Inserts the specified round into the dhttests.rounds table
897 * @param round_type the type of round that is being started
898 * @param round_count counter for the round (if applicable)
900 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
902 int add_round (unsigned int round_type, unsigned int round_count)
908 stmt = mysql_stmt_init(conn);
909 ret = prepared_statement_run (insert_round,
911 MYSQL_TYPE_LONGLONG, ¤t_trial, GNUNET_YES,
912 MYSQL_TYPE_LONG, &round_type, GNUNET_YES,
913 MYSQL_TYPE_LONG, &round_count, GNUNET_YES, -1);
914 mysql_stmt_close(stmt);
915 if (ret != GNUNET_OK)
916 return GNUNET_SYSERR;
921 * Inserts the specified stats into the dhttests.node_statistics table
923 * @param peer the peer inserting the statistic
924 * @param route_requests route requests seen
925 * @param route_forwards route requests forwarded
926 * @param result_requests route result requests seen
927 * @param client_requests client requests initiated
928 * @param result_forwards route results forwarded
929 * @param gets get requests handled
930 * @param puts put requests handle
931 * @param data_inserts data inserted at this node
932 * @param find_peer_requests find peer requests seen
933 * @param find_peers_started find peer requests initiated at this node
934 * @param gets_started get requests initiated at this node
935 * @param puts_started put requests initiated at this node
936 * @param find_peer_responses_received find peer responses received locally
937 * @param get_responses_received get responses received locally
938 * @param find_peer_responses_sent find peer responses sent from this node
939 * @param get_responses_sent get responses sent from this node
941 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
944 add_stat (const struct GNUNET_PeerIdentity *peer, unsigned int route_requests,
945 unsigned int route_forwards, unsigned int result_requests,
946 unsigned int client_requests, unsigned int result_forwards,
947 unsigned int gets, unsigned int puts,
948 unsigned int data_inserts, unsigned int find_peer_requests,
949 unsigned int find_peers_started, unsigned int gets_started,
950 unsigned int puts_started, unsigned int find_peer_responses_received,
951 unsigned int get_responses_received, unsigned int find_peer_responses_sent,
952 unsigned int get_responses_sent)
956 unsigned long long peer_uid;
957 unsigned long long return_uid;
959 return GNUNET_SYSERR;
961 if (GNUNET_OK != get_node_uid (&peer_uid, &peer->hashPubKey))
963 return GNUNET_SYSERR;
966 stmt = mysql_stmt_init(conn);
968 (ret = prepared_statement_run (insert_stat,
970 MYSQL_TYPE_LONGLONG, ¤t_trial, GNUNET_YES,
971 MYSQL_TYPE_LONGLONG, &peer_uid, GNUNET_YES,
972 MYSQL_TYPE_LONG, &route_requests, GNUNET_YES,
973 MYSQL_TYPE_LONG, &route_forwards, GNUNET_YES,
974 MYSQL_TYPE_LONG, &result_requests, GNUNET_YES,
975 MYSQL_TYPE_LONG, &client_requests, GNUNET_YES,
976 MYSQL_TYPE_LONG, &result_forwards, GNUNET_YES,
977 MYSQL_TYPE_LONG, &gets, GNUNET_YES,
978 MYSQL_TYPE_LONG, &puts, GNUNET_YES,
979 MYSQL_TYPE_LONG, &data_inserts, GNUNET_YES,
980 MYSQL_TYPE_LONG, &find_peer_requests, GNUNET_YES,
981 MYSQL_TYPE_LONG, &find_peers_started, GNUNET_YES,
982 MYSQL_TYPE_LONG, &gets_started, GNUNET_YES,
983 MYSQL_TYPE_LONG, &puts_started, GNUNET_YES,
984 MYSQL_TYPE_LONG, &find_peer_responses_received, GNUNET_YES,
985 MYSQL_TYPE_LONG, &get_responses_received, GNUNET_YES,
986 MYSQL_TYPE_LONG, &find_peer_responses_sent, GNUNET_YES,
987 MYSQL_TYPE_LONG, &get_responses_sent, GNUNET_YES,
990 if (ret == GNUNET_SYSERR)
992 mysql_stmt_close(stmt);
993 return GNUNET_SYSERR;
997 mysql_stmt_close(stmt);
1002 * Inserts the specified stats into the dhttests.generic_stats table
1004 * @param peer the peer inserting the statistic
1005 * @param name the name of the statistic
1006 * @param section the section of the statistic
1007 * @param value the value of the statistic
1009 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
1012 add_generic_stat (const struct GNUNET_PeerIdentity *peer,
1014 const char *section, uint64_t value)
1016 unsigned long long peer_uid;
1017 unsigned long long section_len;
1018 unsigned long long name_len;
1021 return GNUNET_SYSERR;
1023 if (GNUNET_OK != get_node_uid (&peer_uid, &peer->hashPubKey))
1025 return GNUNET_SYSERR;
1028 section_len = strlen(section);
1029 name_len = strlen(name);
1032 (ret = prepared_statement_run (insert_generic_stat,
1034 MYSQL_TYPE_LONGLONG, ¤t_trial, GNUNET_YES,
1035 MYSQL_TYPE_LONGLONG, &peer_uid, GNUNET_YES,
1036 MYSQL_TYPE_VAR_STRING, §ion, max_varchar_len, §ion_len,
1037 MYSQL_TYPE_VAR_STRING, &name, max_varchar_len, &name_len,
1038 MYSQL_TYPE_LONGLONG, &value, GNUNET_YES,
1041 if (ret == GNUNET_SYSERR)
1043 return GNUNET_SYSERR;
1050 * Inserts the specified dhtkey into the dhttests.dhtkeys table,
1051 * stores return value of dhttests.dhtkeys.dhtkeyuid into dhtkeyuid
1053 * @param dhtkeyuid return value
1054 * @param dhtkey hashcode of key to insert
1056 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
1059 add_dhtkey (unsigned long long *dhtkeyuid, const GNUNET_HashCode * dhtkey)
1063 struct GNUNET_CRYPTO_HashAsciiEncoded encKey;
1064 unsigned long long k_len;
1065 unsigned long long h_len;
1066 unsigned long long curr_dhtkeyuid;
1067 GNUNET_CRYPTO_hash_to_enc (dhtkey, &encKey);
1068 k_len = strlen ((char *) &encKey);
1069 h_len = sizeof (GNUNET_HashCode);
1071 ret = get_dhtkey_uid(&curr_dhtkeyuid, dhtkey);
1072 if (curr_dhtkeyuid != 0) /* dhtkey already exists */
1074 if (dhtkeyuid != NULL)
1075 *dhtkeyuid = curr_dhtkeyuid;
1078 else if (ret == GNUNET_SYSERR)
1081 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Failed to get dhtkeyuid!\n");
1086 (ret = prepared_statement_run (insert_dhtkey,
1088 MYSQL_TYPE_VAR_STRING,
1097 sizeof (GNUNET_HashCode),
1100 if (ret == GNUNET_SYSERR)
1102 return GNUNET_SYSERR;
1112 * Inserts the specified node into the dhttests.nodes table
1114 * @param nodeuid the inserted node uid
1115 * @param node the node to insert
1117 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
1120 add_node (unsigned long long *nodeuid, struct GNUNET_PeerIdentity * node)
1122 struct GNUNET_CRYPTO_HashAsciiEncoded encPeer;
1123 unsigned long p_len;
1124 unsigned long h_len;
1128 return GNUNET_SYSERR;
1130 GNUNET_CRYPTO_hash_to_enc (&node->hashPubKey, &encPeer);
1131 p_len = (unsigned long) strlen ((char *) &encPeer);
1132 h_len = sizeof (GNUNET_HashCode);
1134 (ret = prepared_statement_run (insert_node,
1136 MYSQL_TYPE_LONGLONG, ¤t_trial, GNUNET_YES,
1137 MYSQL_TYPE_VAR_STRING, &encPeer, max_varchar_len, &p_len,
1138 MYSQL_TYPE_BLOB, &node->hashPubKey, sizeof (GNUNET_HashCode),
1141 if (ret == GNUNET_SYSERR)
1143 return GNUNET_SYSERR;
1150 * Update dhttests.trials table with current server time as end time
1152 * @param trialuid trial to update
1153 * @param gets_succeeded how many gets did the testcase report as successful
1155 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
1158 update_trials (unsigned long long trialuid,
1159 unsigned int gets_succeeded)
1164 (ret = prepared_statement_run (update_trial,
1166 MYSQL_TYPE_LONG, &gets_succeeded, GNUNET_YES,
1167 MYSQL_TYPE_LONGLONG, &trialuid, GNUNET_YES,
1170 if (ret == GNUNET_SYSERR)
1172 return GNUNET_SYSERR;
1178 return GNUNET_SYSERR;
1183 * Update dhttests.nodes table setting the identified
1184 * node as a malicious dropper.
1186 * @param peer the peer that was set to be malicious
1188 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
1190 int set_malicious (struct GNUNET_PeerIdentity *peer)
1192 unsigned long long p_len;
1196 temp_str = GNUNET_strdup(GNUNET_h2s_full(&peer->hashPubKey));
1197 p_len = strlen(temp_str);
1200 (ret = prepared_statement_run (update_node_malicious,
1202 MYSQL_TYPE_LONGLONG, ¤t_trial, GNUNET_YES,
1203 MYSQL_TYPE_VAR_STRING, temp_str, max_varchar_len, &p_len,
1206 if (ret == GNUNET_SYSERR)
1208 return GNUNET_SYSERR;
1216 * Update dhttests.trials table with total connections information
1218 * @param trialuid the trialuid to update
1219 * @param totalConnections the number of connections
1221 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
1224 add_connections (unsigned long long trialuid, unsigned int totalConnections)
1229 (ret = prepared_statement_run (update_connection,
1234 MYSQL_TYPE_LONGLONG,
1235 &trialuid, GNUNET_YES, -1)))
1237 if (ret == GNUNET_SYSERR)
1239 return GNUNET_SYSERR;
1245 return GNUNET_SYSERR;
1249 * Inserts the specified query into the dhttests.queries table
1251 * @param sqlqueruid inserted query uid
1252 * @param queryid dht query id
1253 * @param type type of the query
1254 * @param hops number of hops query traveled
1255 * @param succeeded whether or not query was successful
1256 * @param node the node the query hit
1257 * @param key the key of the query
1259 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
1262 add_query (unsigned long long *sqlqueryuid, unsigned long long queryid,
1263 unsigned int type, unsigned int hops, int succeeded,
1264 const struct GNUNET_PeerIdentity * node, const GNUNET_HashCode * key)
1267 unsigned long long peer_uid, key_uid;
1272 && (GNUNET_OK == get_node_uid (&peer_uid, &node->hashPubKey)))
1278 return GNUNET_SYSERR;
1281 if ((key != NULL) && (GNUNET_OK == get_dhtkey_uid (&key_uid, key)))
1285 else if ((key != NULL) && (key->bits[(512 / 8 / sizeof (unsigned int)) - 1] == 42)) /* Malicious marker */
1291 return GNUNET_SYSERR;
1295 (ret = prepared_statement_run (insert_query,
1297 MYSQL_TYPE_LONGLONG,
1306 MYSQL_TYPE_LONGLONG,
1309 MYSQL_TYPE_LONGLONG,
1315 MYSQL_TYPE_LONGLONG,
1316 &peer_uid, GNUNET_YES, -1)))
1318 if (ret == GNUNET_SYSERR)
1320 return GNUNET_SYSERR;
1326 return GNUNET_SYSERR;
1330 * Inserts the specified route information into the dhttests.routes table
1332 * @param sqlqueruid inserted query uid
1333 * @param queryid dht query id
1334 * @param type type of the query
1335 * @param hops number of hops query traveled
1336 * @param succeeded whether or not query was successful
1337 * @param node the node the query hit
1338 * @param key the key of the query
1339 * @param from_node the node that sent the message to node
1340 * @param to_node next node to forward message to
1342 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
1345 add_route (unsigned long long *sqlqueryuid, unsigned long long queryid,
1346 unsigned int type, unsigned int hops,
1347 int succeeded, const struct GNUNET_PeerIdentity * node,
1348 const GNUNET_HashCode * key, const struct GNUNET_PeerIdentity * from_node,
1349 const struct GNUNET_PeerIdentity * to_node)
1351 unsigned long long peer_uid = 0;
1352 unsigned long long key_uid = 0;
1353 unsigned long long from_uid = 0;
1354 unsigned long long to_uid = 0;
1357 if (from_node != NULL)
1358 get_node_uid (&from_uid, &from_node->hashPubKey);
1360 if (to_node != NULL)
1361 get_node_uid (&to_uid, &to_node->hashPubKey);
1367 if (1 != get_node_uid (&peer_uid, &node->hashPubKey))
1369 return GNUNET_SYSERR;
1373 return GNUNET_SYSERR;
1377 if (1 != get_dhtkey_uid (&key_uid, key))
1379 return GNUNET_SYSERR;
1383 return GNUNET_SYSERR;
1386 (ret = prepared_statement_run (insert_route,
1388 MYSQL_TYPE_LONGLONG,
1397 MYSQL_TYPE_LONGLONG,
1400 MYSQL_TYPE_LONGLONG,
1406 MYSQL_TYPE_LONGLONG,
1409 MYSQL_TYPE_LONGLONG,
1412 MYSQL_TYPE_LONGLONG,
1413 &to_uid, GNUNET_YES, -1)))
1415 if (ret == GNUNET_SYSERR)
1417 return GNUNET_SYSERR;
1423 return GNUNET_SYSERR;
1427 * Update dhttests.topology table with total connections information
1429 * @param totalConnections the number of connections
1431 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
1434 update_current_topology (unsigned int connections)
1437 unsigned long long topologyuid;
1439 get_current_topology(&topologyuid);
1442 (ret = prepared_statement_run (update_topology,
1447 MYSQL_TYPE_LONGLONG,
1448 &topologyuid, GNUNET_YES, -1)))
1450 if (ret == GNUNET_SYSERR)
1452 return GNUNET_SYSERR;
1457 return GNUNET_SYSERR;
1462 * Records the current topology (number of connections, time, trial)
1464 * @param num_connections how many connections are in the topology
1466 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
1469 add_topology (int num_connections)
1474 (ret = prepared_statement_run (insert_topology,
1476 MYSQL_TYPE_LONGLONG, ¤t_trial, GNUNET_YES,
1477 MYSQL_TYPE_LONG, &num_connections, GNUNET_YES,
1480 if (ret == GNUNET_SYSERR)
1482 return GNUNET_SYSERR;
1487 return GNUNET_SYSERR;
1491 * Records a connection between two peers in the current topology
1493 * @param first one side of the connection
1494 * @param second other side of the connection
1496 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
1499 add_extended_topology (const struct GNUNET_PeerIdentity *first, const struct GNUNET_PeerIdentity *second)
1502 unsigned long long first_uid;
1503 unsigned long long second_uid;
1504 unsigned long long topologyuid;
1506 if (GNUNET_OK != get_current_topology(&topologyuid))
1507 return GNUNET_SYSERR;
1508 if (GNUNET_OK != get_node_uid(&first_uid, &first->hashPubKey))
1509 return GNUNET_SYSERR;
1510 if (GNUNET_OK != get_node_uid(&second_uid, &second->hashPubKey))
1511 return GNUNET_SYSERR;
1514 (ret = prepared_statement_run (extend_topology,
1516 MYSQL_TYPE_LONGLONG,
1519 MYSQL_TYPE_LONGLONG,
1522 MYSQL_TYPE_LONGLONG,
1526 if (ret == GNUNET_SYSERR)
1528 return GNUNET_SYSERR;
1533 return GNUNET_SYSERR;
1538 * Provides the dhtlog api
1540 * @param c the configuration to use to connect to a server
1542 * @return the handle to the server, or NULL on error
1545 libgnunet_plugin_dhtlog_mysql_init (void * cls)
1547 struct GNUNET_DHTLOG_Plugin *plugin = cls;
1550 max_varchar_len = 255;
1552 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MySQL DHT Logger: initializing database\n");
1555 if (iopen (plugin) != GNUNET_OK)
1557 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1558 _("Failed to initialize MySQL database connection for dhtlog.\n"));
1562 GNUNET_assert(plugin->dhtlog_api == NULL);
1563 plugin->dhtlog_api = GNUNET_malloc(sizeof(struct GNUNET_DHTLOG_Handle));
1564 plugin->dhtlog_api->insert_trial = &add_trial;
1565 plugin->dhtlog_api->insert_stat = &add_stat;
1566 plugin->dhtlog_api->insert_round = &add_round;
1567 plugin->dhtlog_api->add_generic_stat = &add_generic_stat;
1568 plugin->dhtlog_api->insert_query = &add_query;
1569 plugin->dhtlog_api->update_trial = &update_trials;
1570 plugin->dhtlog_api->insert_route = &add_route;
1571 plugin->dhtlog_api->insert_node = &add_node;
1572 plugin->dhtlog_api->insert_dhtkey = &add_dhtkey;
1573 plugin->dhtlog_api->update_connections = &add_connections;
1574 plugin->dhtlog_api->insert_topology = &add_topology;
1575 plugin->dhtlog_api->update_topology = &update_current_topology;
1576 plugin->dhtlog_api->insert_extended_topology = &add_extended_topology;
1577 plugin->dhtlog_api->set_malicious = &set_malicious;
1578 plugin->dhtlog_api->add_generic_stat = &add_generic_stat;
1579 get_current_trial (¤t_trial);
1585 * Shutdown the plugin.
1588 libgnunet_plugin_dhtlog_mysql_done (void * cls)
1590 struct GNUNET_DHTLOG_Handle *dhtlog_api = cls;
1592 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1593 "MySQL DHT Logger: database shutdown\n");
1594 GNUNET_assert(dhtlog_api != NULL);
1595 prepared_statement_close(insert_query);
1596 prepared_statement_close(insert_route);
1597 prepared_statement_close(insert_trial);
1598 prepared_statement_close(insert_round);
1599 prepared_statement_close(insert_node);
1600 prepared_statement_close(insert_dhtkey);
1601 prepared_statement_close(update_trial);
1602 prepared_statement_close(get_dhtkeyuid);
1603 prepared_statement_close(get_nodeuid);
1604 prepared_statement_close(update_connection);
1605 prepared_statement_close(get_trial);
1606 prepared_statement_close(get_topology);
1607 prepared_statement_close(insert_topology);
1608 prepared_statement_close(update_topology);
1609 prepared_statement_close(extend_topology);
1610 prepared_statement_close(update_node_malicious);
1615 mysql_library_end();
1616 GNUNET_free(dhtlog_api);
1620 /* end of plugin_dhtlog_mysql.c */