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_NO
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 */
91 static char *password;
95 static char *database;
97 static unsigned long long port;
100 * Connection to the MySQL Server.
104 #define INSERT_QUERIES_STMT "INSERT INTO queries (trialuid, querytype, hops, dhtkeyuid, dhtqueryid, succeeded, nodeuid) "\
105 "VALUES (?, ?, ?, ?, ?, ?, ?)"
106 static struct StatementHandle *insert_query;
108 #define INSERT_ROUTES_STMT "INSERT INTO routes (trialuid, querytype, hops, dhtkeyuid, dhtqueryid, succeeded, nodeuid, from_node, to_node) "\
109 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
110 static struct StatementHandle *insert_route;
112 #define INSERT_NODES_STMT "INSERT INTO nodes (trialuid, nodeid, nodebits) "\
114 static struct StatementHandle *insert_node;
116 #define INSERT_TRIALS_STMT "INSERT INTO trials"\
117 "(starttime, numnodes, topology,"\
118 "topology_percentage, topology_probability,"\
119 "blacklist_topology, connect_topology, connect_topology_option,"\
120 "connect_topology_option_modifier, puts, gets, "\
121 "concurrent, settle_time, num_rounds, malicious_getters,"\
122 "malicious_putters, malicious_droppers, message) "\
123 "VALUES (NOW(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
125 static struct StatementHandle *insert_trial;
127 #define INSERT_DHTKEY_STMT "INSERT INTO dhtkeys (dhtkey, trialuid, keybits) "\
129 static struct StatementHandle *insert_dhtkey;
131 #define UPDATE_TRIALS_STMT "UPDATE trials set endtime=NOW(), total_messages_dropped = ?, total_bytes_dropped = ?, unknownPeers = ? where trialuid = ?"
132 static struct StatementHandle *update_trial;
134 #define UPDATE_CONNECTIONS_STMT "UPDATE trials set totalConnections = ? where trialuid = ?"
135 static struct StatementHandle *update_connection;
137 #define GET_TRIAL_STMT "SELECT MAX( trialuid ) FROM trials"
138 static struct StatementHandle *get_trial;
140 #define GET_DHTKEYUID_STMT "SELECT dhtkeyuid FROM dhtkeys where dhtkey = ? and trialuid = ?"
141 static struct StatementHandle *get_dhtkeyuid;
143 #define GET_NODEUID_STMT "SELECT nodeuid FROM nodes where trialuid = ? and nodeid = ?"
144 static struct StatementHandle *get_nodeuid;
147 * Run a query (not a select statement)
149 * @return GNUNET_OK if executed, GNUNET_SYSERR if an error occurred
152 run_statement (const char *statement)
154 mysql_query (conn, statement);
155 if (mysql_error (conn)[0])
157 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
159 return GNUNET_SYSERR;
165 * Creates tables if they don't already exist for dht logging
170 #define MRUNS(a) (GNUNET_OK != run_statement (a) )
172 if (MRUNS ("CREATE TABLE IF NOT EXISTS `dhtkeys` ("
173 "dhtkeyuid int(10) unsigned NOT NULL auto_increment COMMENT 'Unique Key given to each query',"
174 "`dhtkey` varchar(255) NOT NULL COMMENT 'The ASCII value of the key being searched for',"
175 "trialuid int(10) unsigned NOT NULL,"
176 "keybits blob NOT NULL,"
177 "UNIQUE KEY `dhtkeyuid` (`dhtkeyuid`)"
178 ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
179 return GNUNET_SYSERR;
181 if (MRUNS ("CREATE TABLE IF NOT EXISTS `nodes` ("
182 "`nodeuid` int(10) unsigned NOT NULL auto_increment,"
183 "`trialuid` int(10) unsigned NOT NULL,"
184 "`nodeid` varchar(255) NOT NULL,"
185 "`nodebits` blob NOT NULL,"
186 "PRIMARY KEY (`nodeuid`)"
187 ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
188 return GNUNET_SYSERR;
190 if (MRUNS ("CREATE TABLE IF NOT EXISTS `queries` ("
191 "`trialuid` int(10) unsigned NOT NULL,"
192 "`queryuid` int(10) unsigned NOT NULL auto_increment,"
193 "`dhtqueryid` bigint(20) NOT NULL,"
194 "`querytype` enum('1','2','3','4','5') NOT NULL,"
195 "`hops` int(10) unsigned NOT NULL,"
196 "`succeeded` tinyint NOT NULL,"
197 "`nodeuid` int(10) unsigned NOT NULL,"
198 "`time` timestamp NOT NULL default CURRENT_TIMESTAMP,"
199 "`dhtkeyuid` int(10) unsigned NOT NULL,"
200 "PRIMARY KEY (`queryuid`)"
201 ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
202 return GNUNET_SYSERR;
204 if (MRUNS ("CREATE TABLE IF NOT EXISTS `routes` ("
205 "`trialuid` int(10) unsigned NOT NULL,"
206 "`queryuid` int(10) unsigned NOT NULL auto_increment,"
207 "`dhtqueryid` bigint(20) NOT NULL,"
208 "`querytype` enum('1','2','3','4','5') NOT NULL,"
209 "`hops` int(10) unsigned NOT NULL,"
210 "`succeeded` tinyint NOT NULL,"
211 "`nodeuid` int(10) unsigned NOT NULL,"
212 "`time` timestamp NOT NULL default CURRENT_TIMESTAMP,"
213 "`dhtkeyuid` int(10) unsigned NOT NULL,"
214 "`from_node` int(10) unsigned NOT NULL,"
215 "`to_node` int(10) unsigned NOT NULL,"
216 "PRIMARY KEY (`queryuid`)"
217 ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
218 return GNUNET_SYSERR;
220 if (MRUNS ("CREATE TABLE IF NOT EXISTS `trials` ("
221 "`trialuid` int(10) unsigned NOT NULL auto_increment,"
222 "`numnodes` int(10) unsigned NOT NULL,"
223 "`topology` int(10) NOT NULL,"
224 "`starttime` datetime NOT NULL,"
225 "`endtime` datetime NOT NULL,"
226 "`puts` int(10) unsigned NOT NULL,"
227 "`gets` int(10) unsigned NOT NULL,"
228 "`concurrent` int(10) unsigned NOT NULL,"
229 "`settle_time` int(10) unsigned NOT NULL,"
230 "`totalConnections` int(10) unsigned NOT NULL,"
231 "`message` text NOT NULL,"
232 "`num_rounds` int(10) unsigned NOT NULL,"
233 "`malicious_getters` int(10) unsigned NOT NULL,"
234 "`malicious_putters` int(10) unsigned NOT NULL,"
235 "`malicious_droppers` int(10) unsigned NOT NULL,"
236 "`totalMessagesDropped` int(10) unsigned NOT NULL,"
237 "`totalBytesDropped` int(10) unsigned NOT NULL,"
238 "`topology_modifier` double NOT NULL,"
239 "`logNMultiplier` double NOT NULL,"
240 "`maxnetbps` bigint(20) unsigned NOT NULL,"
241 "`unknownPeers` int(10) unsigned NOT NULL,"
242 "PRIMARY KEY (`trialuid`),"
243 "UNIQUE KEY `trialuid` (`trialuid`)"
244 ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
245 return GNUNET_SYSERR;
247 if (MRUNS ("SET AUTOCOMMIT = 1"))
248 return GNUNET_SYSERR;
255 * Create a prepared statement.
257 * @return NULL on error
259 struct StatementHandle *
260 prepared_statement_create (const char *statement)
262 struct StatementHandle *ret;
264 ret = GNUNET_malloc (sizeof (struct StatementHandle));
265 ret->query = GNUNET_strdup (statement);
270 * Create a prepared statement.
272 * @return NULL on error
275 prepared_statement_close (struct StatementHandle *s)
280 if (s->query != NULL)
281 GNUNET_free(s->query);
282 if (s->valid == GNUNET_YES)
283 mysql_stmt_close(s->statement);
288 * Initialize the prepared statements for use with dht test logging
295 conn = mysql_init (NULL);
297 return GNUNET_SYSERR;
299 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to mysql with: user %s, pass %s, server %s, database %s, port %d\n",
300 user, password, server, database, port);
302 mysql_real_connect (conn, server, user, password,
303 database, (unsigned int) port, NULL, 0);
305 if (mysql_error (conn)[0])
307 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
308 "mysql_real_connect");
309 return GNUNET_SYSERR;
313 db = GNUNET_MYSQL_database_open (coreAPI->ectx, coreAPI->cfg);
315 return GNUNET_SYSERR;
320 #define PINIT(a,b) (NULL == (a = prepared_statement_create(b)))
321 if (PINIT (insert_query, INSERT_QUERIES_STMT) ||
322 PINIT (insert_route, INSERT_ROUTES_STMT) ||
323 PINIT (insert_trial, INSERT_TRIALS_STMT) ||
324 PINIT (insert_node, INSERT_NODES_STMT) ||
325 PINIT (insert_dhtkey, INSERT_DHTKEY_STMT) ||
326 PINIT (update_trial, UPDATE_TRIALS_STMT) ||
327 PINIT (get_dhtkeyuid, GET_DHTKEYUID_STMT) ||
328 PINIT (get_nodeuid, GET_NODEUID_STMT) ||
329 PINIT (update_connection, UPDATE_CONNECTIONS_STMT) ||
330 PINIT (get_trial, GET_TRIAL_STMT))
332 return GNUNET_SYSERR;
340 return_ok (void *cls, unsigned int num_values, MYSQL_BIND * values)
346 * Prepare a statement for running.
348 * @return GNUNET_OK on success
351 prepare_statement (struct StatementHandle *ret)
353 if (GNUNET_YES == ret->valid)
356 ret->statement = mysql_stmt_init (conn);
357 if (ret->statement == NULL)
358 return GNUNET_SYSERR;
360 if (mysql_stmt_prepare (ret->statement, ret->query, strlen (ret->query)))
362 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
363 "mysql_stmt_prepare `%s', %s", ret->query, mysql_error(conn));
364 mysql_stmt_close (ret->statement);
365 ret->statement = NULL;
366 return GNUNET_SYSERR;
368 ret->valid = GNUNET_YES;
373 * Bind the parameters for the given MySQL statement
376 * @param s statement to bind and run
377 * @param ap arguments for the binding
378 * @return GNUNET_SYSERR on error, GNUNET_OK on success
381 init_params (struct StatementHandle *s, va_list ap)
383 MYSQL_BIND qbind[MAX_PARAM];
386 enum enum_field_types ft;
388 pc = mysql_stmt_param_count (s->statement);
391 /* increase internal constant! */
393 return GNUNET_SYSERR;
395 memset (qbind, 0, sizeof (qbind));
398 while ((pc > 0) && (-1 != (ft = va_arg (ap, enum enum_field_types))))
400 qbind[off].buffer_type = ft;
403 case MYSQL_TYPE_FLOAT:
404 qbind[off].buffer = va_arg (ap, float *);
406 case MYSQL_TYPE_LONGLONG:
407 qbind[off].buffer = va_arg (ap, unsigned long long *);
408 qbind[off].is_unsigned = va_arg (ap, int);
410 case MYSQL_TYPE_LONG:
411 qbind[off].buffer = va_arg (ap, unsigned int *);
412 qbind[off].is_unsigned = va_arg (ap, int);
414 case MYSQL_TYPE_VAR_STRING:
415 case MYSQL_TYPE_STRING:
416 case MYSQL_TYPE_BLOB:
417 qbind[off].buffer = va_arg (ap, void *);
418 qbind[off].buffer_length = va_arg (ap, unsigned long);
419 qbind[off].length = va_arg (ap, unsigned long *);
422 /* unsupported type */
424 return GNUNET_SYSERR;
429 if (!((pc == 0) && (ft != -1) && (va_arg (ap, int) == -1)))
432 return GNUNET_SYSERR;
434 if (mysql_stmt_bind_param (s->statement, qbind))
436 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
437 _("`%s' failed at %s:%d with error: %s\n"),
438 "mysql_stmt_bind_param",
439 __FILE__, __LINE__, mysql_stmt_error (s->statement));
440 return GNUNET_SYSERR;
443 if (mysql_stmt_execute (s->statement))
445 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
446 _("`%s' failed at %s:%d with error: %s\n"),
447 "mysql_stmt_execute",
448 __FILE__, __LINE__, mysql_stmt_error (s->statement));
449 return GNUNET_SYSERR;
456 * Run a prepared SELECT statement.
458 * @param result_size number of elements in results array
459 * @param results pointer to already initialized MYSQL_BIND
460 * array (of sufficient size) for passing results
461 * @param processor function to call on each result
462 * @param processor_cls extra argument to processor
463 * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective
464 * values (size + buffer-reference for pointers); terminated
466 * @return GNUNET_SYSERR on error, otherwise
467 * the number of successfully affected (or queried) rows
470 prepared_statement_run_select (struct StatementHandle
471 *s, unsigned int result_size,
472 MYSQL_BIND * results,
473 GNUNET_MysqlDataProcessor
474 processor, void *processor_cls,
482 if (GNUNET_OK != prepare_statement (s))
485 return GNUNET_SYSERR;
487 va_start (ap, processor_cls);
488 if (GNUNET_OK != init_params (s, ap))
492 return GNUNET_SYSERR;
495 rsize = mysql_stmt_field_count (s->statement);
496 if (rsize > result_size)
499 return GNUNET_SYSERR;
501 if (mysql_stmt_bind_result (s->statement, results))
503 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
504 _("`%s' failed at %s:%d with error: %s\n"),
505 "mysql_stmt_bind_result",
506 __FILE__, __LINE__, mysql_stmt_error (s->statement));
507 return GNUNET_SYSERR;
513 ret = mysql_stmt_fetch (s->statement);
514 if (ret == MYSQL_NO_DATA)
518 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
519 _("`%s' failed at %s:%d with error: %s\n"),
521 __FILE__, __LINE__, mysql_stmt_error (s->statement));
522 return GNUNET_SYSERR;
524 if (processor != NULL)
525 if (GNUNET_OK != processor (processor_cls, rsize, results))
529 mysql_stmt_reset (s->statement);
534 get_current_trial (unsigned long long *trialuid)
538 memset (rbind, 0, sizeof (rbind));
539 rbind[0].buffer_type = MYSQL_TYPE_LONG;
540 rbind[0].is_unsigned = 1;
541 rbind[0].buffer = trialuid;
544 prepared_statement_run_select (get_trial,
547 return_ok, NULL, -1)))
549 return GNUNET_SYSERR;
557 * Run a prepared statement that does NOT produce results.
559 * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective
560 * values (size + buffer-reference for pointers); terminated
562 * @param insert_id NULL or address where to store the row ID of whatever
563 * was inserted (only for INSERT statements!)
564 * @return GNUNET_SYSERR on error, otherwise
565 * the number of successfully affected rows
568 prepared_statement_run (struct StatementHandle *s,
569 unsigned long long *insert_id, ...)
574 if (GNUNET_OK != prepare_statement(s))
577 return GNUNET_SYSERR;
579 GNUNET_assert(s->valid == GNUNET_YES);
580 if (s->statement == NULL)
581 return GNUNET_SYSERR;
583 va_start (ap, insert_id);
585 if (mysql_stmt_prepare (s->statement, s->query, strlen (s->query)))
587 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "mysql_stmt_prepare ERROR");
588 return GNUNET_SYSERR;
591 if (GNUNET_OK != init_params (s, ap))
594 return GNUNET_SYSERR;
598 affected = mysql_stmt_affected_rows (s->statement);
599 if (NULL != insert_id)
600 *insert_id = (unsigned long long) mysql_stmt_insert_id (s->statement);
601 mysql_stmt_reset (s->statement);
607 * Inserts the specified trial into the dhttests.trials table
609 * @param trialuid return the trialuid of the newly inserted trial
610 * @param num_nodes how many nodes are in the trial
611 * @param topology integer representing topology for this trial
612 * @param blacklist_topology integer representing blacklist topology for this trial
613 * @param connect_topology integer representing connect topology for this trial
614 * @param connect_topology_option integer representing connect topology option
615 * @param connect_topology_option_modifier float to modify connect option
616 * @param topology_percentage percentage modifier for certain topologies
617 * @param topology_probability probability modifier for certain topologies
618 * @param puts number of puts to perform
619 * @param gets number of gets to perform
620 * @param concurrent number of concurrent requests
621 * @param settle_time time to wait between creating topology and starting testing
622 * @param num_rounds number of times to repeat the trial
623 * @param malicious_getters number of malicious GET peers in the trial
624 * @param malicious_putters number of malicious PUT peers in the trial
625 * @param malicious_droppers number of malicious DROP peers in the trial
626 * @param message string to put into DB for this trial
628 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
631 add_trial (unsigned long long *trialuid, int num_nodes, int topology,
632 int blacklist_topology, int connect_topology,
633 int connect_topology_option, float connect_topology_option_modifier,
634 float topology_percentage, float topology_probability,
635 int puts, int gets, int concurrent, int settle_time,
636 int num_rounds, int malicious_getters, int malicious_putters,
637 int malicious_droppers, char *message)
641 unsigned long long m_len;
642 m_len = strlen (message);
644 stmt = mysql_stmt_init(conn);
646 (ret = prepared_statement_run (insert_trial,
655 &topology_percentage,
657 &topology_probability,
665 &connect_topology_option,
668 &connect_topology_option_modifier,
696 max_varchar_len, &m_len,
699 if (ret == GNUNET_SYSERR)
701 mysql_stmt_close(stmt);
702 return GNUNET_SYSERR;
706 get_current_trial (¤t_trial);
708 fprintf (stderr, "Current trial is %llu\n", current_trial);
710 mysql_stmt_close(stmt);
715 get_dhtkey_uid (unsigned long long *dhtkeyuid, const GNUNET_HashCode * key)
718 struct GNUNET_CRYPTO_HashAsciiEncoded encKey;
719 unsigned long long k_len;
720 memset (rbind, 0, sizeof (rbind));
721 rbind[0].buffer_type = MYSQL_TYPE_LONG;
722 rbind[0].is_unsigned = 1;
723 rbind[0].buffer = dhtkeyuid;
724 GNUNET_CRYPTO_hash_to_enc (key, &encKey);
725 k_len = strlen ((char *) &encKey);
728 prepared_statement_run_select (get_dhtkeyuid,
732 MYSQL_TYPE_VAR_STRING,
740 return GNUNET_SYSERR;
747 * Inserts the specified dhtkey into the dhttests.dhtkeys table,
748 * stores return value of dhttests.dhtkeys.dhtkeyuid into dhtkeyuid
750 * @param dhtkeyuid return value
751 * @param dhtkey hashcode of key to insert
753 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
756 add_dhtkey (unsigned long long *dhtkeyuid, const GNUNET_HashCode * dhtkey)
760 struct GNUNET_CRYPTO_HashAsciiEncoded encKey;
761 unsigned long long k_len;
762 unsigned long long h_len;
763 unsigned long long curr_dhtkeyuid;
764 GNUNET_CRYPTO_hash_to_enc (dhtkey, &encKey);
765 k_len = strlen ((char *) &encKey);
766 h_len = sizeof (GNUNET_HashCode);
768 ret = get_dhtkey_uid(&curr_dhtkeyuid, dhtkey);
769 if (curr_dhtkeyuid != 0) /* dhtkey already exists */
771 if (dhtkeyuid != NULL)
772 *dhtkeyuid = curr_dhtkeyuid;
777 (ret = prepared_statement_run (insert_dhtkey,
779 MYSQL_TYPE_VAR_STRING,
788 sizeof (GNUNET_HashCode),
791 if (ret == GNUNET_SYSERR)
793 return GNUNET_SYSERR;
802 get_node_uid (unsigned long long *nodeuid, const GNUNET_HashCode * peerHash)
805 struct GNUNET_CRYPTO_HashAsciiEncoded encPeer;
806 unsigned long long p_len;
809 memset (rbind, 0, sizeof (rbind));
810 rbind[0].buffer_type = MYSQL_TYPE_LONG;
811 rbind[0].buffer = nodeuid;
812 rbind[0].is_unsigned = GNUNET_YES;
814 GNUNET_CRYPTO_hash_to_enc (peerHash, &encPeer);
815 p_len = strlen ((char *) &encPeer);
817 if (1 != (ret = prepared_statement_run_select (get_nodeuid,
825 MYSQL_TYPE_VAR_STRING,
831 fprintf (stderr, "FAILED\n");
833 return GNUNET_SYSERR;
840 * Inserts the specified node into the dhttests.nodes table
842 * @param nodeuid the inserted node uid
843 * @param node the node to insert
845 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
848 add_node (unsigned long long *nodeuid, struct GNUNET_PeerIdentity * node)
850 struct GNUNET_CRYPTO_HashAsciiEncoded encPeer;
856 return GNUNET_SYSERR;
858 GNUNET_CRYPTO_hash_to_enc (&node->hashPubKey, &encPeer);
859 p_len = (unsigned long) strlen ((char *) &encPeer);
860 h_len = sizeof (GNUNET_HashCode);
862 (ret = prepared_statement_run (insert_node,
867 MYSQL_TYPE_VAR_STRING,
873 sizeof (GNUNET_HashCode),
876 if (ret == GNUNET_SYSERR)
878 return GNUNET_SYSERR;
885 * Update dhttests.trials table with current server time as end time
887 * @param trialuid trial to update
888 * @param totalMessagesDropped stats value for messages dropped
889 * @param totalBytesDropped stats value for total bytes dropped
890 * @param unknownPeers stats value for unknown peers
892 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
895 update_trials (unsigned long long trialuid,
896 unsigned long long totalMessagesDropped,
897 unsigned long long totalBytesDropped,
898 unsigned long long unknownPeers)
902 if (trialuid != current_trial)
905 _("Trialuid to update is not equal to current_trial\n"));
909 (ret = prepared_statement_run (update_trial,
912 &totalMessagesDropped,
921 &trialuid, GNUNET_YES, -1)))
923 if (ret == GNUNET_SYSERR)
925 return GNUNET_SYSERR;
931 return GNUNET_SYSERR;
936 * Update dhttests.trials table with total connections information
938 * @param trialuid the trialuid to update
939 * @param totalConnections the number of connections
941 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
944 add_connections (unsigned long long trialuid, unsigned int totalConnections)
948 if (trialuid != current_trial)
951 _("Trialuid to update is not equal to current_trial(!)(?)\n"));
955 (ret = prepared_statement_run (update_connection,
961 &trialuid, GNUNET_YES, -1)))
963 if (ret == GNUNET_SYSERR)
965 return GNUNET_SYSERR;
971 return GNUNET_SYSERR;
975 * Inserts the specified query into the dhttests.queries table
977 * @param sqlqueruid inserted query uid
978 * @param queryid dht query id
979 * @param type type of the query
980 * @param hops number of hops query traveled
981 * @param succeeded whether or not query was successful
982 * @param node the node the query hit
983 * @param key the key of the query
985 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
988 add_query (unsigned long long *sqlqueryuid, unsigned long long queryid,
989 unsigned int type, unsigned int hops, int succeeded,
990 const struct GNUNET_PeerIdentity * node, const GNUNET_HashCode * key)
993 unsigned long long peer_uid, key_uid;
998 && (GNUNET_OK == get_node_uid (&peer_uid, &node->hashPubKey)))
1004 return GNUNET_SYSERR;
1007 if ((key != NULL) && (GNUNET_OK == get_dhtkey_uid (&key_uid, key)))
1011 else if ((key != NULL) && (key->bits[(512 / 8 / sizeof (unsigned int)) - 1] == 42)) /* Malicious marker */
1017 return GNUNET_SYSERR;
1021 (ret = prepared_statement_run (insert_query,
1023 MYSQL_TYPE_LONGLONG,
1032 MYSQL_TYPE_LONGLONG,
1035 MYSQL_TYPE_LONGLONG,
1041 MYSQL_TYPE_LONGLONG,
1042 &peer_uid, GNUNET_YES, -1)))
1044 if (ret == GNUNET_SYSERR)
1046 return GNUNET_SYSERR;
1052 return GNUNET_SYSERR;
1056 * Inserts the specified route information into the dhttests.routes table
1058 * @param sqlqueruid inserted query uid
1059 * @param queryid dht query id
1060 * @param type type of the query
1061 * @param hops number of hops query traveled
1062 * @param succeeded whether or not query was successful
1063 * @param node the node the query hit
1064 * @param key the key of the query
1065 * @param from_node the node that sent the message to node
1066 * @param to_node next node to forward message to
1068 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
1071 add_route (unsigned long long *sqlqueryuid, unsigned long long queryid,
1072 unsigned int type, unsigned int hops,
1073 int succeeded, const struct GNUNET_PeerIdentity * node,
1074 const GNUNET_HashCode * key, const struct GNUNET_PeerIdentity * from_node,
1075 const struct GNUNET_PeerIdentity * to_node)
1077 unsigned long long peer_uid = 0;
1078 unsigned long long key_uid = 0;
1079 unsigned long long from_uid = 0;
1080 unsigned long long to_uid = 0;
1083 if (from_node != NULL)
1084 get_node_uid (&from_uid, &from_node->hashPubKey);
1088 if (to_node != NULL)
1089 get_node_uid (&to_uid, &to_node->hashPubKey);
1095 if (1 != get_node_uid (&peer_uid, &node->hashPubKey))
1097 return GNUNET_SYSERR;
1101 return GNUNET_SYSERR;
1105 if (1 != get_dhtkey_uid (&key_uid, key))
1107 return GNUNET_SYSERR;
1111 return GNUNET_SYSERR;
1114 (ret = prepared_statement_run (insert_route,
1116 MYSQL_TYPE_LONGLONG,
1125 MYSQL_TYPE_LONGLONG,
1128 MYSQL_TYPE_LONGLONG,
1134 MYSQL_TYPE_LONGLONG,
1137 MYSQL_TYPE_LONGLONG,
1140 MYSQL_TYPE_LONGLONG,
1141 &to_uid, GNUNET_YES, -1)))
1143 if (ret == GNUNET_SYSERR)
1145 return GNUNET_SYSERR;
1151 return GNUNET_SYSERR;
1155 * Provides the dhtlog api
1157 * @param c the configuration to use to connect to a server
1159 * @return the handle to the server, or NULL on error
1162 libgnunet_plugin_dhtlog_mysql_init (void * cls)
1164 struct GNUNET_DHTLOG_Plugin *plugin = cls;
1167 max_varchar_len = 255;
1169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MySQL DHT Logger: initializing database\n");
1172 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
1173 "MYSQL", "DATABASE",
1176 database = GNUNET_strdup("gnunet");
1179 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
1180 "MYSQL", "USER", &user))
1182 user = GNUNET_strdup("dht");
1185 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
1186 "MYSQL", "PASSWORD", &password))
1188 password = GNUNET_strdup("dhttest**");
1191 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
1192 "MYSQL", "SERVER", &server))
1194 server = GNUNET_strdup("localhost");
1197 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (plugin->cfg,
1198 "MYSQL", "MYSQL_PORT", &port))
1203 if (iopen () != GNUNET_OK)
1205 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1206 _("Failed to initialize MySQL database connection for dhtlog.\n"));
1209 GNUNET_assert(plugin->dhtlog_api == NULL);
1210 plugin->dhtlog_api = GNUNET_malloc(sizeof(struct GNUNET_DHTLOG_Handle));
1211 plugin->dhtlog_api->insert_trial = &add_trial;
1212 plugin->dhtlog_api->insert_query = &add_query;
1213 plugin->dhtlog_api->update_trial = &update_trials;
1214 plugin->dhtlog_api->insert_route = &add_route;
1215 plugin->dhtlog_api->insert_node = &add_node;
1216 plugin->dhtlog_api->insert_dhtkey = &add_dhtkey;
1217 plugin->dhtlog_api->update_connections = &add_connections;
1218 get_current_trial (¤t_trial);
1224 * Shutdown the plugin.
1227 libgnunet_plugin_dhtlog_mysql_done (void * cls)
1229 struct GNUNET_DHTLOG_Handle *dhtlog_api = cls;
1231 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1232 "MySQL DHT Logger: database shutdown\n");
1234 GNUNET_assert(dhtlog_api != NULL);
1235 prepared_statement_close(insert_query);
1236 prepared_statement_close(insert_route);
1237 prepared_statement_close(insert_trial);
1238 prepared_statement_close(insert_node);
1239 prepared_statement_close(insert_dhtkey);
1240 prepared_statement_close(update_trial);
1241 prepared_statement_close(get_dhtkeyuid);
1242 prepared_statement_close(get_nodeuid);
1243 prepared_statement_close(update_connection);
1244 prepared_statement_close(get_trial);
1249 GNUNET_free(dhtlog_api);
1253 /* end of plugin_dhtlog_mysql.c */