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_dump_load.c
23 * @brief MySQL logging plugin to record DHT operations to MySQL server,
24 * but write all queries to file instead of the actual server
25 * so that they can be imported later. Since the first attempt
26 * (writing out SQL queries) seemed rather time consuming on insert,
27 * this plugin writes out tab separated values instead.
29 * @author Nathan Evans
35 #include "gnunet_util_lib.h"
39 #define DEBUG_DHTLOG GNUNET_YES
42 * Maximum number of supported parameters for a prepared
43 * statement. Increase if needed.
48 static unsigned long max_varchar_len;
51 * The configuration the DHT service is running with
53 static const struct GNUNET_CONFIGURATION_Handle *cfg;
55 #define DATE_STR_SIZE 50
57 static unsigned int topology_count;
60 * File(s) to dump all sql statements to.
63 FILE *generic_stat_outfile;
69 FILE *extended_topology_outfile;
74 static char date[DATE_STR_SIZE];
79 memset (date, 0, DATE_STR_SIZE);
80 tmptr = localtime (&timetmp);
82 strftime (date, DATE_STR_SIZE, "%Y-%m-%d %H:%M:%S", tmptr);
90 * Records the current topology (number of connections, time, trial)
92 * @param num_connections how many connections are in the topology
94 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
97 add_topology (int num_connections)
101 return GNUNET_SYSERR;
103 ret = fprintf(outfile, "insert into topology (trialuid, date, connections) values (@temp_trial, \"%s\", %d);\n", get_sql_time(), num_connections);
105 return GNUNET_SYSERR;
106 ret = fprintf(outfile, "select max(topology_uid) from topology into @temp_topology;\n");
109 return GNUNET_SYSERR;
113 * Inserts the specified round into the dhttests.rounds table
115 * @param round_type the type of round that is being started
116 * @param round_count counter for the round (if applicable)
118 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
120 int add_round (unsigned int round_type, unsigned int round_count)
124 return GNUNET_SYSERR;
126 ret = fprintf(outfile, "insert into rounds (trialuid, round_type, round_count, starttime) values (@temp_trial, \"%u\", \"%u\", \"%s\");\n", round_type, round_count, get_sql_time());
130 return GNUNET_SYSERR;
135 * Inserts the specified round results into the
136 * dhttests.processed_round_details table
138 * @param round_type the type of round that is being started
139 * @param round_count counter for the round (if applicable)
140 * @param num_messages the total number of messages initiated
141 * @param num_messages_succeeded the number of messages that succeeded
143 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
145 int add_round_details (unsigned int round_type, unsigned int round_count,
146 unsigned int num_messages, unsigned int num_messages_succeeded)
150 return GNUNET_SYSERR;
152 ret = fprintf(outfile, "insert into processed_trial_rounds (trialuid, round_type, round_count, starttime, endtime, num_messages, num_messages_succeeded) values (@temp_trial, \"%u\", \"%u\", \"%s\", \"%s\", \"%u\", \"%u\");\n",
153 round_type, round_count, get_sql_time(), get_sql_time(), num_messages, num_messages_succeeded);
157 return GNUNET_SYSERR;
161 * Records a connection between two peers in the current topology
163 * @param first one side of the connection
164 * @param second other side of the connection
166 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
169 add_extended_topology (const struct GNUNET_PeerIdentity *first, const struct GNUNET_PeerIdentity *second)
173 return GNUNET_SYSERR;
175 ret = fprintf(extended_topology_outfile, "insert into extended_topology (topology_uid, uid_first, uid_second) values (%u, %s,", topology_count, GNUNET_h2s_full(&first->hashPubKey));
177 return GNUNET_SYSERR;
178 ret = fprintf(extended_topology_outfile, "%s);\n", GNUNET_h2s_full(&second->hashPubKey));
182 return GNUNET_SYSERR;
187 * Inserts the specified trial into the dhttests.trials table
189 * @param trial_info struct containing the data to insert about this trial
191 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
193 int add_trial (struct GNUNET_DHTLOG_TrialInfo *trial_info)
197 return GNUNET_SYSERR;
199 ret = fprintf(outfile, "INSERT INTO trials "
200 "(starttime, other_trial_identifier, numnodes, topology,"
201 "blacklist_topology, connect_topology, connect_topology_option,"
202 "connect_topology_option_modifier, topology_percentage, topology_probability,"
204 "concurrent, settle_time, num_rounds, malicious_getters,"
205 "malicious_putters, malicious_droppers, malicious_get_frequency,"
206 "malicious_put_frequency, stop_closest, stop_found, strict_kademlia, "
207 "gets_succeeded, message) "
208 "VALUES (\"%s\", %u, %u, %u, %u, %u, %u, %f, %f, %f, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, \"%s\");\n",
209 get_sql_time(), trial_info->other_identifier, trial_info->num_nodes, trial_info->topology,
210 trial_info->blacklist_topology, trial_info->connect_topology,
211 trial_info->connect_topology_option, trial_info->connect_topology_option_modifier,
212 trial_info->topology_percentage, trial_info->topology_probability,
213 trial_info->puts, trial_info->gets, trial_info->concurrent, trial_info->settle_time,
214 trial_info->num_rounds, trial_info->malicious_getters, trial_info->malicious_putters,
215 trial_info->malicious_droppers, trial_info->malicious_get_frequency, trial_info->malicious_put_frequency,
216 trial_info->stop_closest, trial_info->stop_found, trial_info->strict_kademlia, trial_info->gets_succeeded, trial_info->message);
219 return GNUNET_SYSERR;
221 ret = fprintf(outfile, "SELECT MAX( trialuid ) FROM trials into @temp_trial;\n");
226 return GNUNET_SYSERR;
231 * Inserts the specified stats into the dhttests.generic_stats table
233 * @param peer the peer inserting the statistic
234 * @param name the name of the statistic
235 * @param section the section of the statistic
236 * @param value the value of the statistic
238 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
241 add_generic_stat (const struct GNUNET_PeerIdentity *peer,
243 const char *section, uint64_t value)
246 return GNUNET_SYSERR;
249 fprintf(generic_stat_outfile, "TRIALUID\t%s\t%s\t%s\t%llu\n", GNUNET_h2s_full(&peer->hashPubKey), section, name, (unsigned long long)value);
256 * Inserts the specified stats into the dhttests.node_statistics table
258 * @param peer the peer inserting the statistic
259 * @param route_requests route requests seen
260 * @param route_forwards route requests forwarded
261 * @param result_requests route result requests seen
262 * @param client_requests client requests initiated
263 * @param result_forwards route results forwarded
264 * @param gets get requests handled
265 * @param puts put requests handle
266 * @param data_inserts data inserted at this node
267 * @param find_peer_requests find peer requests seen
268 * @param find_peers_started find peer requests initiated at this node
269 * @param gets_started get requests initiated at this node
270 * @param puts_started put requests initiated at this node
271 * @param find_peer_responses_received find peer responses received locally
272 * @param get_responses_received get responses received locally
273 * @param find_peer_responses_sent find peer responses sent from this node
274 * @param get_responses_sent get responses sent from this node
276 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
279 add_stat (const struct GNUNET_PeerIdentity *peer, unsigned int route_requests,
280 unsigned int route_forwards, unsigned int result_requests,
281 unsigned int client_requests, unsigned int result_forwards,
282 unsigned int gets, unsigned int puts,
283 unsigned int data_inserts, unsigned int find_peer_requests,
284 unsigned int find_peers_started, unsigned int gets_started,
285 unsigned int puts_started, unsigned int find_peer_responses_received,
286 unsigned int get_responses_received, unsigned int find_peer_responses_sent,
287 unsigned int get_responses_sent)
291 return GNUNET_SYSERR;
294 ret = fprintf(stat_outfile, "TRIALUID\t%s\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\n",
295 GNUNET_h2s_full(&peer->hashPubKey),
296 route_requests, route_forwards, result_requests,
297 client_requests, result_forwards, gets, puts,
298 data_inserts, find_peer_requests, find_peers_started,
299 gets_started, puts_started, find_peer_responses_received,
300 get_responses_received, find_peer_responses_sent,
304 return GNUNET_SYSERR;
309 return GNUNET_SYSERR;
312 * Inserts the specified dhtkey into the dhttests.dhtkeys table,
313 * stores return value of dhttests.dhtkeys.dhtkeyuid into dhtkeyuid
315 * @param dhtkeyuid return value
316 * @param dhtkey hashcode of key to insert
318 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
321 add_dhtkey (unsigned long long *dhtkeyuid, const GNUNET_HashCode * dhtkey)
324 if (dhtkeyuid != NULL)
327 if ((dhtkey_outfile == NULL) || (dhtkey == NULL))
328 return GNUNET_SYSERR;
330 ret = fprintf(dhtkey_outfile, "TRIALUID\t%s\n", GNUNET_h2s_full(dhtkey));
335 return GNUNET_SYSERR;
339 * Inserts the specified node into the dhttests.nodes table
341 * @param nodeuid the inserted node uid
342 * @param node the node to insert
344 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
347 add_node (unsigned long long *nodeuid, struct GNUNET_PeerIdentity * node)
351 if ((node == NULL) || (node_outfile == NULL))
352 return GNUNET_SYSERR;
354 ret = fprintf(node_outfile, "TRIALUID\t%s\n", GNUNET_h2s_full(&node->hashPubKey));
355 fflush(node_outfile);
358 return GNUNET_SYSERR;
362 * Update dhttests.trials table with current server time as end time
364 * @param gets_succeeded how many gets did the testcase report as successful
366 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
369 update_trials (unsigned int gets_succeeded)
374 return GNUNET_SYSERR;
376 ret = fprintf(outfile, "update trials set endtime=\"%s\", gets_succeeded=%u where trialuid = @temp_trial;\n", get_sql_time(), gets_succeeded);
377 fflush(node_outfile);
381 return GNUNET_SYSERR;
386 * Update dhttests.nodes table setting the identified
387 * node as a malicious dropper.
389 * @param peer the peer that was set to be malicious
391 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
394 set_malicious (struct GNUNET_PeerIdentity *peer)
399 return GNUNET_SYSERR;
401 ret = fprintf(outfile, "update nodes set malicious_dropper = 1 where trialuid = @temp_trial and nodeid = \"%s\";\n", GNUNET_h2s_full(&peer->hashPubKey));
402 fflush(node_outfile);
406 return GNUNET_SYSERR;
411 * Update dhttests.trials table with total connections information
413 * @param totalConnections the number of connections
415 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
418 add_connections (unsigned int totalConnections)
423 return GNUNET_SYSERR;
425 ret = fprintf(outfile, "update trials set totalConnections = %u where trialuid = @temp_trial;\n", totalConnections);
426 fflush(node_outfile);
430 return GNUNET_SYSERR;
435 * Update dhttests.topology table with total connections information
437 * @param connections the number of connections
439 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
442 update_topology (unsigned int connections)
446 return GNUNET_SYSERR;
448 ret = fprintf(outfile, "update topology set connections = %u where topology_uid = @temp_topology;\n", connections);
453 return GNUNET_SYSERR;
457 * Inserts the specified query into the dhttests.queries table
459 * @param sqlqueruid inserted query uid
460 * @param queryid dht query id
461 * @param type type of the query
462 * @param hops number of hops query traveled
463 * @param succeeded whether or not query was successful
464 * @param node the node the query hit
465 * @param key the key of the query
467 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
470 add_query (unsigned long long *sqlqueryuid, unsigned long long queryid,
471 unsigned int type, unsigned int hops, int succeeded,
472 const struct GNUNET_PeerIdentity * node, const GNUNET_HashCode * key)
476 if ((outfile == NULL) || (node == NULL) || (key == NULL))
477 return GNUNET_SYSERR;
479 if (sqlqueryuid != NULL)
482 ret = fprintf(query_outfile, "TRIALUID\t%s\t", GNUNET_h2s_full(key));
485 return GNUNET_SYSERR;
487 ret = fprintf(query_outfile, "%s\t%llu\t%u\t%u\t%u\t%s\n", GNUNET_h2s_full(&node->hashPubKey), queryid, type, hops, succeeded, get_sql_time());
492 return GNUNET_SYSERR;
496 * Inserts the specified route information into the dhttests.routes table
498 * @param sqlqueruid inserted query uid
499 * @param queryid dht query id
500 * @param type type of the query
501 * @param hops number of hops query traveled
502 * @param succeeded whether or not query was successful
503 * @param node the node the query hit
504 * @param key the key of the query
505 * @param from_node the node that sent the message to node
506 * @param to_node next node to forward message to
508 * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
511 add_route (unsigned long long *sqlqueryuid, unsigned long long queryid,
512 unsigned int type, unsigned int hops,
513 int succeeded, const struct GNUNET_PeerIdentity * node,
514 const GNUNET_HashCode * key, const struct GNUNET_PeerIdentity * from_node,
515 const struct GNUNET_PeerIdentity * to_node)
519 if ((outfile == NULL) || (node == NULL) || (key == NULL))
520 return GNUNET_SYSERR;
522 if (sqlqueryuid != NULL)
525 ret = fprintf(route_outfile, "TRIALUID\t%s\t", GNUNET_h2s_full(key));
527 return GNUNET_SYSERR;
529 ret = fprintf(route_outfile, "%s\t", GNUNET_h2s_full(&node->hashPubKey));
531 return GNUNET_SYSERR;
532 if (from_node == NULL)
533 ret = fprintf(route_outfile, "0\t");
535 ret = fprintf(route_outfile, "%s\t", GNUNET_h2s_full(&from_node->hashPubKey));
537 return GNUNET_SYSERR;
540 ret = fprintf(route_outfile, "0\t%llu\t%u\t%u\t%d\n", queryid, type, hops, succeeded);
542 ret = fprintf(route_outfile, "%s\t%llu\t%u\t%u\t%d\n", GNUNET_h2s_full(&to_node->hashPubKey), queryid, type, hops, succeeded);
547 return GNUNET_SYSERR;
551 * Provides the dhtlog api
553 * @param c the configuration to use to connect to a server
555 * @return the handle to the server, or NULL on error
558 libgnunet_plugin_dhtlog_mysql_dump_load_init (void * cls)
560 struct GNUNET_DHTLOG_Plugin *plugin = cls;
567 max_varchar_len = 255;
569 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MySQL (DUMP) DHT Logger: initializing\n");
571 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
575 outfile_path = GNUNET_strdup("");
578 GNUNET_asprintf (&outfile_name,
584 fn = GNUNET_STRINGS_filename_expand (outfile_name);
588 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
589 GNUNET_free(outfile_path);
590 GNUNET_free(outfile_name);
594 dirwarn = (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn));
595 outfile = FOPEN (fn, "w");
599 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
601 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
602 _("Failed to create or access directory for log file `%s'\n"),
604 GNUNET_free(outfile_path);
605 GNUNET_free(outfile_name);
610 GNUNET_free(outfile_name);
611 GNUNET_asprintf (&outfile_name,
617 fn = GNUNET_STRINGS_filename_expand (outfile_name);
621 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
622 GNUNET_free(outfile_path);
623 GNUNET_free(outfile_name);
627 dirwarn = (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn));
628 node_outfile = FOPEN (fn, "w");
630 if (node_outfile == NULL)
632 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
634 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
635 _("Failed to create or access directory for log file `%s'\n"),
637 GNUNET_free(outfile_path);
638 GNUNET_free(outfile_name);
643 GNUNET_free(outfile_name);
644 GNUNET_asprintf (&outfile_name,
651 fn = GNUNET_STRINGS_filename_expand (outfile_name);
655 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
656 GNUNET_free(outfile_path);
657 GNUNET_free(outfile_name);
661 dirwarn = (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn));
662 route_outfile = FOPEN (fn, "w");
664 if (route_outfile == NULL)
666 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
668 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
669 _("Failed to create or access directory for log file `%s'\n"),
671 GNUNET_free(outfile_path);
672 GNUNET_free(outfile_name);
677 GNUNET_free(outfile_name);
678 GNUNET_asprintf (&outfile_name,
685 fn = GNUNET_STRINGS_filename_expand (outfile_name);
689 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
690 GNUNET_free(outfile_path);
691 GNUNET_free(outfile_name);
695 dirwarn = (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn));
696 query_outfile = FOPEN (fn, "w");
698 if (query_outfile == NULL)
700 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
702 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
703 _("Failed to create or access directory for log file `%s'\n"),
705 GNUNET_free(outfile_path);
706 GNUNET_free(outfile_name);
711 GNUNET_free(outfile_name);
712 GNUNET_asprintf (&outfile_name,
719 fn = GNUNET_STRINGS_filename_expand (outfile_name);
723 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
724 GNUNET_free(outfile_path);
725 GNUNET_free(outfile_name);
729 dirwarn = (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn));
730 stat_outfile = FOPEN (fn, "w");
732 if (stat_outfile == NULL)
734 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
736 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
737 _("Failed to create or access directory for log file `%s'\n"),
739 GNUNET_free(outfile_path);
740 GNUNET_free(outfile_name);
745 GNUNET_free(outfile_name);
746 GNUNET_asprintf (&outfile_name,
749 "mysqldump_generic_stats",
752 fn = GNUNET_STRINGS_filename_expand (outfile_name);
756 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
757 GNUNET_free(outfile_path);
758 GNUNET_free(outfile_name);
762 dirwarn = (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn));
763 generic_stat_outfile = FOPEN (fn, "w");
765 if (generic_stat_outfile == NULL)
767 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
769 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
770 _("Failed to create or access directory for log file `%s'\n"),
772 GNUNET_free(outfile_path);
773 GNUNET_free(outfile_name);
778 GNUNET_free(outfile_name);
779 GNUNET_asprintf (&outfile_name,
785 fn = GNUNET_STRINGS_filename_expand (outfile_name);
789 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
790 GNUNET_free(outfile_path);
791 GNUNET_free(outfile_name);
795 dirwarn = (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn));
796 dhtkey_outfile = FOPEN (fn, "w");
798 if (dhtkey_outfile == NULL)
800 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
802 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
803 _("Failed to create or access directory for log file `%s'\n"),
805 GNUNET_free(outfile_path);
806 GNUNET_free(outfile_name);
811 GNUNET_free(outfile_name);
812 GNUNET_asprintf (&outfile_name,
815 "mysqldump_extended_topology",
818 fn = GNUNET_STRINGS_filename_expand (outfile_name);
822 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
823 GNUNET_free(outfile_path);
824 GNUNET_free(outfile_name);
828 dirwarn = (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn));
829 extended_topology_outfile = FOPEN (fn, "w");
831 if (extended_topology_outfile == NULL)
833 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
835 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
836 _("Failed to create or access directory for log file `%s'\n"),
838 GNUNET_free(outfile_path);
839 GNUNET_free(outfile_name);
844 GNUNET_free (outfile_path);
845 GNUNET_free (outfile_name);
848 GNUNET_assert(plugin->dhtlog_api == NULL);
849 plugin->dhtlog_api = GNUNET_malloc(sizeof(struct GNUNET_DHTLOG_Handle));
850 plugin->dhtlog_api->insert_trial = &add_trial;
851 plugin->dhtlog_api->insert_stat = &add_stat;
852 plugin->dhtlog_api->insert_round = &add_round;
853 plugin->dhtlog_api->insert_round_details = &add_round_details;
854 plugin->dhtlog_api->insert_query = &add_query;
855 plugin->dhtlog_api->update_trial = &update_trials;
856 plugin->dhtlog_api->insert_route = &add_route;
857 plugin->dhtlog_api->insert_node = &add_node;
858 plugin->dhtlog_api->insert_dhtkey = &add_dhtkey;
859 plugin->dhtlog_api->update_connections = &add_connections;
860 plugin->dhtlog_api->insert_topology = &add_topology;
861 plugin->dhtlog_api->insert_extended_topology = &add_extended_topology;
862 plugin->dhtlog_api->update_topology = &update_topology;
863 plugin->dhtlog_api->set_malicious = &set_malicious;
864 plugin->dhtlog_api->add_generic_stat = &add_generic_stat;
870 * Shutdown the plugin.
873 libgnunet_plugin_dhtlog_mysql_dump_load_done (void * cls)
875 struct GNUNET_DHTLOG_Handle *dhtlog_api = cls;
876 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
877 "MySQL DHT Logger: database shutdown\n");
878 GNUNET_assert(dhtlog_api != NULL);
881 fclose(node_outfile);
882 fclose(query_outfile);
883 fclose(route_outfile);
884 fclose(stat_outfile);
885 fclose(generic_stat_outfile);
886 fclose(extended_topology_outfile);
887 GNUNET_free(dhtlog_api);
891 /* end of plugin_dhtlog_mysql_dump_load.c */