WiP
[oweals/gnunet.git] / src / dht / plugin_dhtlog_mysql.c
index 7798263c4beed5e68df8248ed03841d3ff7e8b4b..0cce99d6d8f7bc050cf3049268bddbb9f2bef3e6 100644 (file)
@@ -32,7 +32,7 @@
 #include <mysql/mysql.h>
 
 
-#define DEBUG_DHTLOG GNUNET_NO
+#define DEBUG_DHTLOG GNUNET_YES
 
 /**
  * Maximum number of supported parameters for a prepared
@@ -86,23 +86,13 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
 
 static unsigned long long current_trial = 0;    /* I like to assign 0, just to remember */
 
-static char *user;
-
-static char *password;
-
-static char *server;
-
-static char *database;
-
-static unsigned long long port;
-
 /**
  * Connection to the MySQL Server.
  */
 static MYSQL *conn;
 
-#define INSERT_QUERIES_STMT "INSERT INTO queries (trialuid, querytype, hops, dhtkeyuid, dhtqueryid, succeeded, nodeuid) "\
-                          "VALUES (?, ?, ?, ?, ?, ?, ?)"
+#define INSERT_QUERIES_STMT "INSERT INTO queries (trialuid, querytype, hops, dhtkeyuid, dhtqueryid, succeeded, nodeuid, time) "\
+                          "VALUES (?, ?, ?, ?, ?, ?, ?, NOW())"
 static struct StatementHandle *insert_query;
 
 #define INSERT_ROUTES_STMT "INSERT INTO routes (trialuid, querytype, hops, dhtkeyuid, dhtqueryid, succeeded, nodeuid, from_node, to_node) "\
@@ -113,22 +103,50 @@ static struct StatementHandle *insert_route;
                           "VALUES (?, ?, ?)"
 static struct StatementHandle *insert_node;
 
+#define INSERT_ROUNDS_STMT "INSERT INTO rounds (trialuid, round_type, round_count, starttime) "\
+                          "VALUES (?, ?, ?, NOW())"
+
+static struct StatementHandle *insert_round;
+
+#define INSERT_ROUND_DETAILS_STMT "INSERT INTO rounds (trialuid, round_type, round_count, starttime, endtime, num_messages, num_messages_succeeded) "\
+                          "VALUES (?, ?, ?, NOW(), NOW(), ?, ?)"
+
+static struct StatementHandle *insert_round_details;
+
 #define INSERT_TRIALS_STMT "INSERT INTO trials"\
-                            "(starttime, numnodes, topology,"\
+                            "(starttime, other_trial_identifier, numnodes, topology,"\
                             "topology_percentage, topology_probability,"\
                             "blacklist_topology, connect_topology, connect_topology_option,"\
                             "connect_topology_option_modifier, puts, gets, "\
                             "concurrent, settle_time, num_rounds, malicious_getters,"\
-                            "malicious_putters, malicious_droppers, message) "\
-                            "VALUES (NOW(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
+                            "malicious_putters, malicious_droppers, malicious_get_frequency,"\
+                            "malicious_put_frequency, stop_closest, stop_found, strict_kademlia, "\
+                            "gets_succeeded, message) "\
+                            "VALUES (NOW(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
 
 static struct StatementHandle *insert_trial;
 
+#define INSERT_STAT_STMT "INSERT INTO node_statistics"\
+                            "(trialuid, nodeuid, route_requests,"\
+                            "route_forwards, result_requests,"\
+                            "client_results, result_forwards, gets,"\
+                            "puts, data_inserts, find_peer_requests, "\
+                            "find_peers_started, gets_started, puts_started, find_peer_responses_received,"\
+                            "get_responses_received, find_peer_responses_sent, get_responses_sent) "\
+                            "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
+
+static struct StatementHandle *insert_stat;
+
+#define INSERT_GENERIC_STAT_STMT "INSERT INTO generic_stats" \
+                                 "(trialuid, nodeuid, section, name, value)"\
+                                 "VALUES (?, ?, ?, ?, ?)"
+static struct StatementHandle *insert_generic_stat;
+
 #define INSERT_DHTKEY_STMT "INSERT INTO dhtkeys (dhtkey, trialuid, keybits) "\
                           "VALUES (?, ?, ?)"
 static struct StatementHandle *insert_dhtkey;
 
-#define UPDATE_TRIALS_STMT "UPDATE trials set endtime=NOW(), total_messages_dropped = ?, total_bytes_dropped = ?, unknownPeers = ? where trialuid = ?"
+#define UPDATE_TRIALS_STMT "UPDATE trials set endtime=NOW(), gets_succeeded = ? where trialuid = ?"
 static struct StatementHandle *update_trial;
 
 #define UPDATE_CONNECTIONS_STMT "UPDATE trials set totalConnections = ? where trialuid = ?"
@@ -154,6 +172,9 @@ static struct StatementHandle *insert_topology;
                              "VALUES (?, ?, ?)"
 static struct StatementHandle *extend_topology;
 
+#define SET_MALICIOUS_STMT "update nodes set malicious_dropper = 1  where trialuid = ? and nodeid = ?"
+static struct StatementHandle *update_node_malicious;
+
 #define UPDATE_TOPOLOGY_STMT "update topology set connections = ?  where topology_uid = ?"
 static struct StatementHandle *update_topology;
 
@@ -232,30 +253,38 @@ itable ()
     return GNUNET_SYSERR;
 
   if (MRUNS ("CREATE TABLE IF NOT EXISTS `trials` ("
-             "`trialuid` int(10) unsigned NOT NULL auto_increment,"
-             "`numnodes` int(10) unsigned NOT NULL,"
-             "`topology` int(10) NOT NULL,"
-             "`starttime` datetime NOT NULL,"
-             "`endtime` datetime NOT NULL,"
-             "`puts` int(10) unsigned NOT NULL,"
-             "`gets` int(10) unsigned NOT NULL,"
-             "`concurrent` int(10) unsigned NOT NULL,"
-             "`settle_time` int(10) unsigned NOT NULL,"
-             "`totalConnections` int(10) unsigned NOT NULL,"
-             "`message` text NOT NULL,"
-             "`num_rounds` int(10) unsigned NOT NULL,"
-             "`malicious_getters` int(10) unsigned NOT NULL,"
-             "`malicious_putters` int(10) unsigned NOT NULL,"
-             "`malicious_droppers` int(10) unsigned NOT NULL,"
-             "`totalMessagesDropped` int(10) unsigned NOT NULL,"
-             "`totalBytesDropped` int(10) unsigned NOT NULL,"
-             "`topology_modifier` double NOT NULL,"
-             "`logNMultiplier` double NOT NULL,"
-             "`maxnetbps` bigint(20) unsigned NOT NULL,"
-             "`unknownPeers` int(10) unsigned NOT NULL,"
-             "PRIMARY KEY  (`trialuid`),"
-             "UNIQUE KEY `trialuid` (`trialuid`)"
-             ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
+              "`trialuid` int(10) unsigned NOT NULL auto_increment,"
+              "`other_trial_identifier` int(10) unsigned NOT NULL default '0',"
+              "`numnodes` int(10) unsigned NOT NULL,"
+              "`topology` int(10) NOT NULL,"
+              "`blacklist_topology` int(11) NOT NULL,"
+              "`connect_topology` int(11) NOT NULL,"
+              "`connect_topology_option` int(11) NOT NULL,"
+              "`topology_percentage` float NOT NULL,"
+              "`topology_probability` float NOT NULL,"
+              "`connect_topology_option_modifier` float NOT NULL,"
+              "`starttime` datetime NOT NULL,"
+              "`endtime` datetime NOT NULL,"
+              "`puts` int(10) unsigned NOT NULL,"
+              "`gets` int(10) unsigned NOT NULL,"
+              "`concurrent` int(10) unsigned NOT NULL,"
+              "`settle_time` int(10) unsigned NOT NULL,"
+              "`totalConnections` int(10) unsigned NOT NULL,"
+              "`message` text NOT NULL,"
+              "`num_rounds` int(10) unsigned NOT NULL,"
+              "`malicious_getters` int(10) unsigned NOT NULL,"
+              "`malicious_putters` int(10) unsigned NOT NULL,"
+              "`malicious_droppers` int(10) unsigned NOT NULL,"
+              "`topology_modifier` double NOT NULL,"
+              "`malicious_get_frequency` int(10) unsigned NOT NULL,"
+              "`malicious_put_frequency` int(10) unsigned NOT NULL,"
+              "`stop_closest` int(10) unsigned NOT NULL,"
+              "`stop_found` int(10) unsigned NOT NULL,"
+              "`strict_kademlia` int(10) unsigned NOT NULL,"
+              "`gets_succeeded` int(10) unsigned NOT NULL,"
+              "PRIMARY KEY  (`trialuid`),"
+              "UNIQUE KEY `trialuid` (`trialuid`)"
+              ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
     return GNUNET_SYSERR;
 
   if (MRUNS ("CREATE TABLE IF NOT EXISTS `topology` ("
@@ -275,6 +304,30 @@ itable ()
              ") ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"))
     return GNUNET_SYSERR;
 
+  if (MRUNS ("CREATE TABLE IF NOT EXISTS `node_statistics` ("
+              "`stat_uid` int(10) unsigned NOT NULL AUTO_INCREMENT,"
+              "`trialuid` int(10) unsigned NOT NULL,"
+              "`nodeuid` int(10) unsigned NOT NULL,"
+              "`route_requests` int(10) unsigned NOT NULL,"
+              "`route_forwards` int(10) unsigned NOT NULL,"
+              "`result_requests` int(10) unsigned NOT NULL,"
+              "`client_results` int(10) unsigned NOT NULL,"
+              "`result_forwards` int(10) unsigned NOT NULL,"
+              "`gets` int(10) unsigned NOT NULL,"
+              "`puts` int(10) unsigned NOT NULL,"
+              "`data_inserts` int(10) unsigned NOT NULL,"
+              "`find_peer_requests` int(10) unsigned NOT NULL,"
+              "`find_peers_started` int(10) unsigned NOT NULL,"
+              "`gets_started` int(10) unsigned NOT NULL,"
+              "`puts_started` int(10) unsigned NOT NULL,"
+              "`find_peer_responses_received` int(10) unsigned NOT NULL,"
+              "`get_responses_received` int(10) unsigned NOT NULL,"
+              "`find_peer_responses_sent` int(10) unsigned NOT NULL,"
+              "`get_responses_sent` int(10) unsigned NOT NULL,"
+             "PRIMARY KEY (`stat_uid`)"
+            ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;"))
+    return GNUNET_SYSERR;
+
   if (MRUNS ("SET AUTOCOMMIT = 1"))
     return GNUNET_SYSERR;
 
@@ -298,7 +351,7 @@ prepared_statement_create (const char *statement)
 }
 
 /**
- * Create a prepared statement.
+ * Close a prepared statement.
  *
  * @return NULL on error
  */
@@ -306,10 +359,12 @@ void
 prepared_statement_close (struct StatementHandle *s)
 {
   if (s == NULL)
-    return;
+    {
+      return;
+    }
+
+  GNUNET_free_non_null(s->query);
 
-  if (s->query != NULL)
-    GNUNET_free(s->query);
   if (s->valid == GNUNET_YES)
     mysql_stmt_close(s->statement);
   GNUNET_free(s);
@@ -319,19 +374,70 @@ prepared_statement_close (struct StatementHandle *s)
  * Initialize the prepared statements for use with dht test logging
  */
 static int
-iopen ()
+iopen (struct GNUNET_DHTLOG_Plugin *plugin)
 {
   int ret;
+  my_bool reconnect;
+  unsigned int timeout;
+  char *user;
+  char *password;
+  char *server;
+  char *database;
+  unsigned long long port;
 
   conn = mysql_init (NULL);
   if (conn == NULL)
     return GNUNET_SYSERR;
 
+  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
+                                                         "MYSQL", "DATABASE",
+                                                         &database))
+    {
+      database = GNUNET_strdup("gnunet");
+    }
+
+  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
+                                                          "MYSQL", "USER", &user))
+    {
+      user = GNUNET_strdup("dht");
+    }
+
+  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
+                                                          "MYSQL", "PASSWORD", &password))
+    {
+      password = GNUNET_strdup("dhttest**");
+    }
+
+  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
+                                                          "MYSQL", "SERVER", &server))
+    {
+      server = GNUNET_strdup("localhost");
+    }
+
+  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (plugin->cfg,
+                                                          "MYSQL", "MYSQL_PORT", &port))
+    {
+      port = 0;
+    }
+
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to mysql with: user %s, pass %s, server %s, database %s, port %d\n",
               user, password, server, database, port);
 
+  reconnect = 0;
+  timeout = 60; /* in seconds */
+  mysql_options (conn, MYSQL_OPT_RECONNECT, &reconnect);
+  mysql_options (conn,
+                 MYSQL_OPT_CONNECT_TIMEOUT, (const void *) &timeout);
+  mysql_options(conn, MYSQL_SET_CHARSET_NAME, "UTF8");
+  mysql_options (conn, MYSQL_OPT_READ_TIMEOUT, (const void *) &timeout);
+  mysql_options (conn, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout);
   mysql_real_connect (conn, server, user, password,
-                      database, (unsigned int) port, NULL, 0);
+                      database, (unsigned int) port, NULL, CLIENT_IGNORE_SIGPIPE);
+
+  GNUNET_free_non_null(server);
+  GNUNET_free_non_null(password);
+  GNUNET_free_non_null(user);
+  GNUNET_free_non_null(database);
 
   if (mysql_error (conn)[0])
     {
@@ -352,6 +458,10 @@ iopen ()
   if (PINIT (insert_query, INSERT_QUERIES_STMT) ||
       PINIT (insert_route, INSERT_ROUTES_STMT) ||
       PINIT (insert_trial, INSERT_TRIALS_STMT) ||
+      PINIT (insert_round, INSERT_ROUNDS_STMT) ||
+      PINIT (insert_round, INSERT_ROUND_DETAILS_STMT) ||
+      PINIT (insert_stat, INSERT_STAT_STMT) ||
+      PINIT (insert_generic_stat, INSERT_GENERIC_STAT_STMT) ||
       PINIT (insert_node, INSERT_NODES_STMT) ||
       PINIT (insert_dhtkey, INSERT_DHTKEY_STMT) ||
       PINIT (update_trial, UPDATE_TRIALS_STMT) ||
@@ -360,9 +470,10 @@ iopen ()
       PINIT (update_connection, UPDATE_CONNECTIONS_STMT) ||
       PINIT (get_trial, GET_TRIAL_STMT) ||
       PINIT (get_topology, GET_TOPOLOGY_STMT) ||
-      PINIT (insert_topology, INSERT_TOPOLOGY_STMT)||
-      PINIT (update_topology, UPDATE_TOPOLOGY_STMT)||
-      PINIT (extend_topology, EXTEND_TOPOLOGY_STMT))
+      PINIT (insert_topology, INSERT_TOPOLOGY_STMT) ||
+      PINIT (update_topology, UPDATE_TOPOLOGY_STMT) ||
+      PINIT (extend_topology, EXTEND_TOPOLOGY_STMT) ||
+      PINIT (update_node_malicious, SET_MALICIOUS_STMT) )
     {
       return GNUNET_SYSERR;
     }
@@ -490,7 +601,8 @@ init_params (struct StatementHandle *s, va_list ap)
 /**
  * Run a prepared SELECT statement.
  *
- * @param result_size number of elements in results array
+ * @param s handle to the statement we should execute
+ * @param result_size number of results in set
  * @param results pointer to already initialized MYSQL_BIND
  *        array (of sufficient size) for passing results
  * @param processor function to call on each result
@@ -498,12 +610,13 @@ init_params (struct StatementHandle *s, va_list ap)
  * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective
  *        values (size + buffer-reference for pointers); terminated
  *        with "-1"
+ *
  * @return GNUNET_SYSERR on error, otherwise
  *         the number of successfully affected (or queried) rows
  */
 int
-prepared_statement_run_select (struct StatementHandle
-                               *s, unsigned int result_size,
+prepared_statement_run_select (struct StatementHandle *s,
+                               unsigned int result_size,
                                MYSQL_BIND * results,
                                GNUNET_MysqlDataProcessor
                                processor, void *processor_cls,
@@ -575,7 +688,7 @@ get_node_uid (unsigned long long *nodeuid, const GNUNET_HashCode * peerHash)
 
   int ret;
   memset (rbind, 0, sizeof (rbind));
-  rbind[0].buffer_type = MYSQL_TYPE_LONG;
+  rbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
   rbind[0].buffer = nodeuid;
   rbind[0].is_unsigned = GNUNET_YES;
 
@@ -587,7 +700,7 @@ get_node_uid (unsigned long long *nodeuid, const GNUNET_HashCode * peerHash)
                                                               rbind,
                                                               return_ok,
                                                               NULL,
-                                                              MYSQL_TYPE_LONG,
+                                                              MYSQL_TYPE_LONGLONG,
                                                               &current_trial,
                                                               GNUNET_YES,
                                                               MYSQL_TYPE_VAR_STRING,
@@ -659,7 +772,9 @@ get_dhtkey_uid (unsigned long long *dhtkeyuid, const GNUNET_HashCode * key)
   rbind[0].buffer = dhtkeyuid;
   GNUNET_CRYPTO_hash_to_enc (key, &encKey);
   k_len = strlen ((char *) &encKey);
-
+#if DEBUG_DHTLOG
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Searching for dhtkey `%s' in trial %llu\n", GNUNET_h2s(key), current_trial);
+#endif
   if ((GNUNET_OK !=
        prepared_statement_run_select (get_dhtkeyuid,
                                       1,
@@ -682,11 +797,13 @@ get_dhtkey_uid (unsigned long long *dhtkeyuid, const GNUNET_HashCode * key)
 /**
  * Run a prepared statement that does NOT produce results.
  *
+ * @param s handle to the statement we should execute
+ * @param insert_id NULL or address where to store the row ID of whatever
+ *        was inserted (only for INSERT statements!)
  * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective
  *        values (size + buffer-reference for pointers); terminated
  *        with "-1"
- * @param insert_id NULL or address where to store the row ID of whatever
- *        was inserted (only for INSERT statements!)
+ *
  * @return GNUNET_SYSERR on error, otherwise
  *         the number of successfully affected rows
  */
@@ -708,12 +825,6 @@ prepared_statement_run (struct StatementHandle *s,
 
   va_start (ap, insert_id);
 
-  if (mysql_stmt_prepare (s->statement, s->query, strlen (s->query)))
-      {
-        GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "mysql_stmt_prepare ERROR");
-        return GNUNET_SYSERR;
-      }
-
   if (GNUNET_OK != init_params (s, ap))
     {
       va_end (ap);
@@ -732,94 +843,45 @@ prepared_statement_run (struct StatementHandle *s,
 /*
  * Inserts the specified trial into the dhttests.trials table
  *
- * @param trialuid return the trialuid of the newly inserted trial
- * @param num_nodes how many nodes are in the trial
- * @param topology integer representing topology for this trial
- * @param blacklist_topology integer representing blacklist topology for this trial
- * @param connect_topology integer representing connect topology for this trial
- * @param connect_topology_option integer representing connect topology option
- * @param connect_topology_option_modifier float to modify connect option
- * @param topology_percentage percentage modifier for certain topologies
- * @param topology_probability probability modifier for certain topologies
- * @param puts number of puts to perform
- * @param gets number of gets to perform
- * @param concurrent number of concurrent requests
- * @param settle_time time to wait between creating topology and starting testing
- * @param num_rounds number of times to repeat the trial
- * @param malicious_getters number of malicious GET peers in the trial
- * @param malicious_putters number of malicious PUT peers in the trial
- * @param malicious_droppers number of malicious DROP peers in the trial
- * @param message string to put into DB for this trial
+ * @param trial_info struct containing the data to insert about this trial
  *
  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
  */
-int
-add_trial (unsigned long long *trialuid, int num_nodes, int topology,
-           int blacklist_topology, int connect_topology,
-           int connect_topology_option, float connect_topology_option_modifier,
-           float topology_percentage, float topology_probability,
-           int puts, int gets, int concurrent, int settle_time,
-           int num_rounds, int malicious_getters, int malicious_putters,
-           int malicious_droppers, char *message)
+int add_trial (struct GNUNET_DHTLOG_TrialInfo *trial_info)
 {
   MYSQL_STMT *stmt;
   int ret;
   unsigned long long m_len;
-  m_len = strlen (message);
+  m_len = strlen (trial_info->message);
 
   stmt = mysql_stmt_init(conn);
   if (GNUNET_OK !=
-      (ret = prepared_statement_run (insert_trial,
-                                      trialuid,
-                                      MYSQL_TYPE_LONG,
-                                      &num_nodes,
-                                      GNUNET_YES,
-                                      MYSQL_TYPE_LONG,
-                                      &topology,
-                                      GNUNET_YES,
-                                      MYSQL_TYPE_FLOAT,
-                                      &topology_percentage,
-                                      MYSQL_TYPE_FLOAT,
-                                      &topology_probability,
-                                      MYSQL_TYPE_LONG,
-                                      &blacklist_topology,
-                                      GNUNET_YES,
-                                      MYSQL_TYPE_LONG,
-                                      &connect_topology,
-                                      GNUNET_YES,
-                                      MYSQL_TYPE_LONG,
-                                      &connect_topology_option,
-                                      GNUNET_YES,
-                                      MYSQL_TYPE_FLOAT,
-                                      &connect_topology_option_modifier,
-                                      MYSQL_TYPE_LONG,
-                                      &puts,
-                                      GNUNET_YES,
-                                      MYSQL_TYPE_LONG,
-                                      &gets,
-                                      GNUNET_YES,
-                                      MYSQL_TYPE_LONG,
-                                      &concurrent,
-                                      GNUNET_YES,
-                                      MYSQL_TYPE_LONG,
-                                      &settle_time,
-                                      GNUNET_YES,
-                                      MYSQL_TYPE_LONG,
-                                      &num_rounds,
-                                      GNUNET_YES,
-                                      MYSQL_TYPE_LONG,
-                                      &malicious_getters,
-                                      GNUNET_YES,
-                                      MYSQL_TYPE_LONG,
-                                      &malicious_putters,
-                                      GNUNET_YES,
-                                      MYSQL_TYPE_LONG,
-                                      &malicious_droppers,
-                                      GNUNET_YES,
-                                      MYSQL_TYPE_BLOB,
-                                      message,
-                                      max_varchar_len +
-                                      max_varchar_len, &m_len,
+      (ret = prepared_statement_run (insert_trial, &current_trial,
+                                     MYSQL_TYPE_LONG, &trial_info->other_identifier, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->num_nodes, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->topology, GNUNET_YES,
+                                     MYSQL_TYPE_FLOAT, &trial_info->topology_percentage,
+                                     MYSQL_TYPE_FLOAT, &trial_info->topology_probability,
+                                     MYSQL_TYPE_LONG, &trial_info->blacklist_topology, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->connect_topology, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->connect_topology_option, GNUNET_YES,
+                                     MYSQL_TYPE_FLOAT, &trial_info->connect_topology_option_modifier,
+                                     MYSQL_TYPE_LONG, &trial_info->puts, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->gets, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->concurrent, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->settle_time, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->num_rounds, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->malicious_getters, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->malicious_putters, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->malicious_droppers, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->malicious_get_frequency, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->malicious_put_frequency, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->stop_closest, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->stop_found, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->strict_kademlia, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &trial_info->gets_succeeded, GNUNET_YES,
+                                     MYSQL_TYPE_BLOB, trial_info->message, max_varchar_len +
+                                     max_varchar_len, &m_len,
                                       -1)))
     {
       if (ret == GNUNET_SYSERR)
@@ -830,13 +892,198 @@ add_trial (unsigned long long *trialuid, int num_nodes, int topology,
     }
 
   get_current_trial (&current_trial);
-#if DEBUG_DHTLOG
-  fprintf (stderr, "Current trial is %llu\n", current_trial);
-#endif
+
+  mysql_stmt_close(stmt);
+  return GNUNET_OK;
+}
+
+/*
+ * Inserts the specified round into the dhttests.rounds table
+ *
+ * @param round_type the type of round that is being started
+ * @param round_count counter for the round (if applicable)
+ *
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int add_round (unsigned int round_type, unsigned int round_count)
+{
+
+  MYSQL_STMT *stmt;
+  int ret;
+
+  stmt = mysql_stmt_init(conn);
+  ret = prepared_statement_run (insert_round,
+                                NULL,
+                                MYSQL_TYPE_LONGLONG, &current_trial, GNUNET_YES,
+                                MYSQL_TYPE_LONG, &round_type, GNUNET_YES,
+                                MYSQL_TYPE_LONG, &round_count, GNUNET_YES, -1);
+  mysql_stmt_close(stmt);
+  if (ret != GNUNET_OK)
+    return GNUNET_SYSERR;
+  return ret;
+}
+
+/*
+ * Inserts the specified round results into the
+ * dhttests.processed_round_details table
+ *
+ * @param round_type the type of round that is being started
+ * @param round_count counter for the round (if applicable)
+ * @param num_messages the total number of messages initiated
+ * @param num_messages_succeeded the number of messages that succeeded
+ *
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int add_round_details (unsigned int round_type, unsigned int round_count,
+                       unsigned int num_messages, unsigned int num_messages_succeeded)
+{
+  MYSQL_STMT *stmt;
+  int ret;
+
+  stmt = mysql_stmt_init(conn);
+  ret = prepared_statement_run (insert_round_details,
+                                NULL,
+                                MYSQL_TYPE_LONGLONG, &current_trial, GNUNET_YES,
+                                MYSQL_TYPE_LONG, &round_type, GNUNET_YES,
+                                MYSQL_TYPE_LONG, &round_count, GNUNET_YES,
+                                MYSQL_TYPE_LONG, &num_messages, GNUNET_YES,
+                                MYSQL_TYPE_LONG, &num_messages_succeeded, GNUNET_YES,
+                                -1);
+  mysql_stmt_close(stmt);
+  if (ret != GNUNET_OK)
+    return GNUNET_SYSERR;
+  return ret;
+}
+
+/*
+ * Inserts the specified stats into the dhttests.node_statistics table
+ *
+ * @param peer the peer inserting the statistic
+ * @param route_requests route requests seen
+ * @param route_forwards route requests forwarded
+ * @param result_requests route result requests seen
+ * @param client_requests client requests initiated
+ * @param result_forwards route results forwarded
+ * @param gets get requests handled
+ * @param puts put requests handle
+ * @param data_inserts data inserted at this node
+ * @param find_peer_requests find peer requests seen
+ * @param find_peers_started find peer requests initiated at this node
+ * @param gets_started get requests initiated at this node
+ * @param puts_started put requests initiated at this node
+ * @param find_peer_responses_received find peer responses received locally
+ * @param get_responses_received get responses received locally
+ * @param find_peer_responses_sent find peer responses sent from this node
+ * @param get_responses_sent get responses sent from this node
+ *
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int
+add_stat (const struct GNUNET_PeerIdentity *peer, unsigned int route_requests,
+          unsigned int route_forwards, unsigned int result_requests,
+          unsigned int client_requests, unsigned int result_forwards,
+          unsigned int gets, unsigned int puts,
+          unsigned int data_inserts, unsigned int find_peer_requests,
+          unsigned int find_peers_started, unsigned int gets_started,
+          unsigned int puts_started, unsigned int find_peer_responses_received,
+          unsigned int get_responses_received, unsigned int find_peer_responses_sent,
+          unsigned int get_responses_sent)
+{
+  MYSQL_STMT *stmt;
+  int ret;
+  unsigned long long peer_uid;
+  unsigned long long return_uid;
+  if (peer == NULL)
+    return GNUNET_SYSERR;
+
+  if (GNUNET_OK != get_node_uid (&peer_uid, &peer->hashPubKey))
+    {
+      return GNUNET_SYSERR;
+    }
+
+  stmt = mysql_stmt_init(conn);
+  if (GNUNET_OK !=
+      (ret = prepared_statement_run (insert_stat,
+                                     &return_uid,
+                                     MYSQL_TYPE_LONGLONG, &current_trial, GNUNET_YES,
+                                     MYSQL_TYPE_LONGLONG, &peer_uid, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &route_requests, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &route_forwards, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &result_requests, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &client_requests, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &result_forwards, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &gets, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &puts, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &data_inserts, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &find_peer_requests, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &find_peers_started, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &gets_started, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &puts_started, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &find_peer_responses_received, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &get_responses_received, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &find_peer_responses_sent, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &get_responses_sent, GNUNET_YES,
+                                     -1)))
+    {
+      if (ret == GNUNET_SYSERR)
+        {
+          mysql_stmt_close(stmt);
+          return GNUNET_SYSERR;
+        }
+    }
+
   mysql_stmt_close(stmt);
   return GNUNET_OK;
 }
 
+/*
+ * Inserts the specified stats into the dhttests.generic_stats table
+ *
+ * @param peer the peer inserting the statistic
+ * @param name the name of the statistic
+ * @param section the section of the statistic
+ * @param value the value of the statistic
+ *
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int
+add_generic_stat (const struct GNUNET_PeerIdentity *peer,
+                  const char *name,
+                  const char *section, uint64_t value)
+{
+  unsigned long long peer_uid;
+  unsigned long long section_len;
+  unsigned long long name_len;
+  int ret;
+  if (peer == NULL)
+    return GNUNET_SYSERR;
+
+  if (GNUNET_OK != get_node_uid (&peer_uid, &peer->hashPubKey))
+    {
+      return GNUNET_SYSERR;
+    }
+
+  section_len = strlen(section);
+  name_len = strlen(name);
+
+  if (GNUNET_OK !=
+      (ret = prepared_statement_run (insert_generic_stat,
+                                     NULL,
+                                     MYSQL_TYPE_LONGLONG, &current_trial, GNUNET_YES,
+                                     MYSQL_TYPE_LONGLONG, &peer_uid, GNUNET_YES,
+                                     MYSQL_TYPE_VAR_STRING, &section, max_varchar_len, &section_len,
+                                     MYSQL_TYPE_VAR_STRING, &name, max_varchar_len, &name_len,
+                                     MYSQL_TYPE_LONGLONG, &value, GNUNET_YES,
+                                     -1)))
+    {
+      if (ret == GNUNET_SYSERR)
+        {
+          return GNUNET_SYSERR;
+        }
+    }
+  return GNUNET_OK;
+}
+
 /*
  * Inserts the specified dhtkey into the dhttests.dhtkeys table,
  * stores return value of dhttests.dhtkeys.dhtkeyuid into dhtkeyuid
@@ -866,6 +1113,12 @@ add_dhtkey (unsigned long long *dhtkeyuid, const GNUNET_HashCode * dhtkey)
         *dhtkeyuid = curr_dhtkeyuid;
       return GNUNET_OK;
     }
+  else if (ret == GNUNET_SYSERR)
+    {
+#if DEBUG_DHTLOG
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Failed to get dhtkeyuid!\n");
+#endif
+    }
 
   if (GNUNET_OK !=
       (ret = prepared_statement_run (insert_dhtkey,
@@ -917,18 +1170,11 @@ add_node (unsigned long long *nodeuid, struct GNUNET_PeerIdentity * node)
   h_len = sizeof (GNUNET_HashCode);
   if (GNUNET_OK !=
       (ret = prepared_statement_run (insert_node,
-                                                  nodeuid,
-                                                  MYSQL_TYPE_LONGLONG,
-                                                  &current_trial,
-                                                  GNUNET_YES,
-                                                  MYSQL_TYPE_VAR_STRING,
-                                                  &encPeer,
-                                                  max_varchar_len,
-                                                  &p_len,
-                                                  MYSQL_TYPE_BLOB,
-                                                  &node->hashPubKey,
-                                                  sizeof (GNUNET_HashCode),
-                                                  &h_len, -1)))
+                                     nodeuid,
+                                     MYSQL_TYPE_LONGLONG, &current_trial, GNUNET_YES,
+                                     MYSQL_TYPE_VAR_STRING, &encPeer, max_varchar_len, &p_len,
+                                     MYSQL_TYPE_BLOB, &node->hashPubKey, sizeof (GNUNET_HashCode),
+                                     &h_len, -1)))
     {
       if (ret == GNUNET_SYSERR)
         {
@@ -941,41 +1187,21 @@ add_node (unsigned long long *nodeuid, struct GNUNET_PeerIdentity * node)
 /*
  * Update dhttests.trials table with current server time as end time
  *
- * @param trialuid trial to update
- * @param totalMessagesDropped stats value for messages dropped
- * @param totalBytesDropped stats value for total bytes dropped
- * @param unknownPeers stats value for unknown peers
+ * @param gets_succeeded how many gets did the testcase report as successful
  *
  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
  */
 int
-update_trials (unsigned long long trialuid,
-               unsigned long long totalMessagesDropped,
-               unsigned long long totalBytesDropped,
-               unsigned long long unknownPeers)
+update_trials (unsigned int gets_succeeded)
 {
   int ret;
-#if DEBUG_DHTLOG
-  if (trialuid != current_trial)
-    {
-      fprintf (stderr,
-               _("Trialuid to update is not equal to current_trial\n"));
-    }
-#endif
+
   if (GNUNET_OK !=
       (ret = prepared_statement_run (update_trial,
                                     NULL,
-                                    MYSQL_TYPE_LONGLONG,
-                                    &totalMessagesDropped,
-                                    GNUNET_YES,
-                                    MYSQL_TYPE_LONGLONG,
-                                    &totalBytesDropped,
-                                    GNUNET_YES,
-                                    MYSQL_TYPE_LONGLONG,
-                                    &unknownPeers,
-                                    GNUNET_YES,
-                                    MYSQL_TYPE_LONGLONG,
-                                    &trialuid, GNUNET_YES, -1)))
+                                    MYSQL_TYPE_LONG, &gets_succeeded, GNUNET_YES,
+                                    MYSQL_TYPE_LONGLONG, &current_trial, GNUNET_YES,
+                                    -1)))
     {
       if (ret == GNUNET_SYSERR)
         {
@@ -989,25 +1215,51 @@ update_trials (unsigned long long trialuid,
 }
 
 
+/*
+ * Update dhttests.nodes table setting the identified
+ * node as a malicious dropper.
+ *
+ * @param peer the peer that was set to be malicious
+ *
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
+ */
+int set_malicious (struct GNUNET_PeerIdentity *peer)
+{
+  unsigned long long p_len;
+  int ret;
+  char *temp_str;
+
+  temp_str = GNUNET_strdup(GNUNET_h2s_full(&peer->hashPubKey));
+  p_len = strlen(temp_str);
+
+  if (GNUNET_OK !=
+      (ret = prepared_statement_run (update_node_malicious,
+                                    NULL,
+                                    MYSQL_TYPE_LONGLONG, &current_trial, GNUNET_YES,
+                                    MYSQL_TYPE_VAR_STRING, temp_str, max_varchar_len, &p_len,
+                                    -1)))
+    {
+      if (ret == GNUNET_SYSERR)
+        {
+          return GNUNET_SYSERR;
+        }
+    }
+  return GNUNET_OK;
+}
+
+
 /*
  * Update dhttests.trials table with total connections information
  *
- * @param trialuid the trialuid to update
  * @param totalConnections the number of connections
  *
  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
  */
 int
-add_connections (unsigned long long trialuid, unsigned int totalConnections)
+add_connections (unsigned int totalConnections)
 {
   int ret;
-#if DEBUG_DHTLOG
-  if (trialuid != current_trial)
-    {
-      fprintf (stderr,
-               _("Trialuid to update is not equal to current_trial(!)(?)\n"));
-    }
-#endif
+
   if (GNUNET_OK !=
       (ret = prepared_statement_run (update_connection,
                                                   NULL,
@@ -1015,7 +1267,7 @@ add_connections (unsigned long long trialuid, unsigned int totalConnections)
                                                   &totalConnections,
                                                   GNUNET_YES,
                                                   MYSQL_TYPE_LONGLONG,
-                                                  &trialuid, GNUNET_YES, -1)))
+                                                  &current_trial, GNUNET_YES, -1)))
     {
       if (ret == GNUNET_SYSERR)
         {
@@ -1139,8 +1391,6 @@ add_route (unsigned long long *sqlqueryuid, unsigned long long queryid,
 
   if (from_node != NULL)
     get_node_uid (&from_uid, &from_node->hashPubKey);
-  else
-    from_uid = 0;
 
   if (to_node != NULL)
     get_node_uid (&to_uid, &to_node->hashPubKey);
@@ -1239,9 +1489,8 @@ update_current_topology (unsigned int connections)
     }
   if (ret > 0)
     return GNUNET_OK;
-  else
-    return GNUNET_SYSERR;
-  return GNUNET_OK;
+  return GNUNET_SYSERR;
+
 }
 
 /*
@@ -1259,12 +1508,9 @@ add_topology (int num_connections)
   if (GNUNET_OK !=
       (ret = prepared_statement_run (insert_topology,
                                      NULL,
-                                     MYSQL_TYPE_LONGLONG,
-                                     &current_trial,
-                                     GNUNET_YES,
-                                     MYSQL_TYPE_LONG,
-                                     &num_connections,
-                                     GNUNET_YES, -1)))
+                                     MYSQL_TYPE_LONGLONG, &current_trial, GNUNET_YES,
+                                     MYSQL_TYPE_LONG, &num_connections, GNUNET_YES,
+                                     -1)))
     {
       if (ret == GNUNET_SYSERR)
         {
@@ -1273,9 +1519,7 @@ add_topology (int num_connections)
     }
   if (ret > 0)
     return GNUNET_OK;
-  else
-    return GNUNET_SYSERR;
-  return GNUNET_OK;
+  return GNUNET_SYSERR;
 }
 
 /*
@@ -1287,7 +1531,7 @@ add_topology (int num_connections)
  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
  */
 int
-add_extended_topology (struct GNUNET_PeerIdentity *first, struct GNUNET_PeerIdentity *second)
+add_extended_topology (const struct GNUNET_PeerIdentity *first, const struct GNUNET_PeerIdentity *second)
 {
   int ret;
   unsigned long long first_uid;
@@ -1321,9 +1565,7 @@ add_extended_topology (struct GNUNET_PeerIdentity *first, struct GNUNET_PeerIden
     }
   if (ret > 0)
     return GNUNET_OK;
-  else
-    return GNUNET_SYSERR;
-  return GNUNET_OK;
+  return GNUNET_SYSERR;
 }
 
 
@@ -1345,46 +1587,20 @@ libgnunet_plugin_dhtlog_mysql_init (void * cls)
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MySQL DHT Logger: initializing database\n");
 #endif
 
-  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
-                                                         "MYSQL", "DATABASE",
-                                                         &database))
-    {
-      database = GNUNET_strdup("gnunet");
-    }
-
-  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
-                                                          "MYSQL", "USER", &user))
-    {
-      user = GNUNET_strdup("dht");
-    }
-
-  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
-                                                          "MYSQL", "PASSWORD", &password))
-    {
-      password = GNUNET_strdup("dhttest**");
-    }
-
-  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
-                                                          "MYSQL", "SERVER", &server))
-    {
-      server = GNUNET_strdup("localhost");
-    }
-
-  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (plugin->cfg,
-                                                          "MYSQL", "MYSQL_PORT", &port))
-    {
-      port = 0;
-    }
-
-  if (iopen () != GNUNET_OK)
+  if (iopen (plugin) != GNUNET_OK)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                   _("Failed to initialize MySQL database connection for dhtlog.\n"));
       return NULL;
     }
+
   GNUNET_assert(plugin->dhtlog_api == NULL);
   plugin->dhtlog_api = GNUNET_malloc(sizeof(struct GNUNET_DHTLOG_Handle));
   plugin->dhtlog_api->insert_trial = &add_trial;
+  plugin->dhtlog_api->insert_stat = &add_stat;
+  plugin->dhtlog_api->insert_round = &add_round;
+  plugin->dhtlog_api->insert_round_details = &add_round_details;
+  plugin->dhtlog_api->add_generic_stat = &add_generic_stat;
   plugin->dhtlog_api->insert_query = &add_query;
   plugin->dhtlog_api->update_trial = &update_trials;
   plugin->dhtlog_api->insert_route = &add_route;
@@ -1394,9 +1610,11 @@ libgnunet_plugin_dhtlog_mysql_init (void * cls)
   plugin->dhtlog_api->insert_topology = &add_topology;
   plugin->dhtlog_api->update_topology = &update_current_topology;
   plugin->dhtlog_api->insert_extended_topology = &add_extended_topology;
+  plugin->dhtlog_api->set_malicious = &set_malicious;
+  plugin->dhtlog_api->add_generic_stat = &add_generic_stat;
   get_current_trial (&current_trial);
 
-  return NULL;
+  return plugin;
 }
 
 /**
@@ -1406,14 +1624,15 @@ void *
 libgnunet_plugin_dhtlog_mysql_done (void * cls)
 {
   struct GNUNET_DHTLOG_Handle *dhtlog_api = cls;
-#if DEBUG_DHTLOG
+
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "MySQL DHT Logger: database shutdown\n");
-#endif
   GNUNET_assert(dhtlog_api != NULL);
   prepared_statement_close(insert_query);
   prepared_statement_close(insert_route);
   prepared_statement_close(insert_trial);
+  prepared_statement_close(insert_round);
+  prepared_statement_close(insert_round_details);
   prepared_statement_close(insert_node);
   prepared_statement_close(insert_dhtkey);
   prepared_statement_close(update_trial);
@@ -1425,10 +1644,12 @@ libgnunet_plugin_dhtlog_mysql_done (void * cls)
   prepared_statement_close(insert_topology);
   prepared_statement_close(update_topology);
   prepared_statement_close(extend_topology);
+  prepared_statement_close(update_node_malicious);
 
   if (conn != NULL)
     mysql_close (conn);
-
+  conn = NULL;
+  mysql_library_end();
   GNUNET_free(dhtlog_api);
   return NULL;
 }