90485a59de103d99828924eff8a7d87593df19fc
[oweals/gnunet.git] / src / dht / plugin_dhtlog_mysql_dump.c
1 /*
2      This file is part of GNUnet.
3      (C) 2006 - 2009 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 2, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file src/dht/plugin_dhtlog_mysql_dump.c
23  * @brief MySQL logging plugin to record DHT operations to MySQL server,
24  *        but write all queries to file instead of the actual server
25  *        so that they can be imported later.  The idea is that connecting
26  *        to the MySQL server X times can be really problematic, but hopefully
27  *        writing to a single file is more reliable.
28  * @author Nathan Evans
29  *
30  * Database: MySQL
31  */
32
33 #include "platform.h"
34 #include "gnunet_util_lib.h"
35 #include "dhtlog.h"
36
37
38 #define DEBUG_DHTLOG GNUNET_YES
39
40 /**
41  * Maximum number of supported parameters for a prepared
42  * statement.  Increase if needed.
43  */
44 #define MAX_PARAM 32
45
46
47 static unsigned long max_varchar_len;
48
49 /**
50  * The configuration the DHT service is running with
51  */
52 static const struct GNUNET_CONFIGURATION_Handle *cfg;
53
54 #define INSERT_QUERIES_STMT "prepare insert_query from 'INSERT INTO queries (trialuid, querytype, hops, dhtkeyuid, dhtqueryid, succeeded, nodeuid, time) "\
55                           "VALUES (@temp_trial, ?, ?, ?, ?, ?, ?, ?)'"
56
57 #define INSERT_ROUTES_STMT "prepare insert_route from 'INSERT INTO routes (trialuid, querytype, hops, dhtkeyuid, dhtqueryid, succeeded, nodeuid, from_node, to_node) "\
58                           "VALUES (@temp_trial, ?, ?, ?, ?, ?, ?, ?, ?)'"
59
60 #define INSERT_NODES_STMT "prepare insert_node from 'INSERT ignore INTO nodes (trialuid, nodeid) "\
61                           "VALUES (@temp_trial, ?)'"
62
63 #define INSERT_TOPOLOGY_STMT "prepare insert_topology from 'INSERT INTO topology (trialuid, date, connections) "\
64                              "VALUES (@temp_trial, ?, ?)'"
65
66 #define INSERT_ROUND_STMT "prepare insert_round from 'INSERT INTO rounds (trialuid, round_type, round_count, starttime) VALUES (@temp_trial, @rtype, @rcount, @curr_time)'"
67
68 #define INSERT_ROUND_DETAILS_STMT "prepare insert_round_details from 'INSERT INTO processed_trial_rounds "\
69                                   "(trialuid, round_type, round_count, starttime, endtime, num_messages, num_messages_succeeded)"\
70                                   "VALUES (@temp_trial, @rtype, @rcount, @curr_time, @curr_time, @totalmsgs, @msgssucceeded)'"
71
72 #define EXTEND_TOPOLOGY_STMT "prepare extend_topology from 'INSERT INTO extended_topology (topology_uid, uid_first, uid_second) "\
73                              "VALUES (@temp_topology, ?, ?)'"
74
75 #define UPDATE_TOPOLOGY_STMT "prepare update_topology from 'update topology set connections = ?  where topology_uid = @temp_topology'"
76
77 #define SET_MALICIOUS_STMT "prepare set_malicious from 'update nodes set malicious_dropper = 1  where trialuid = @temp_trial and nodeid = @temp_node'"
78
79 #define INSERT_TRIALS_STMT "prepare insert_trial from 'INSERT INTO trials"\
80                            "(starttime, other_trial_identifier, numnodes, topology,"\
81                            "topology_percentage, topology_probability,"\
82                            "blacklist_topology, connect_topology, connect_topology_option,"\
83                            "connect_topology_option_modifier, puts, gets, "\
84                            "concurrent, settle_time, num_rounds, malicious_getters,"\
85                            "malicious_putters, malicious_droppers, malicious_get_frequency,"\
86                            "malicious_put_frequency, stop_closest, stop_found, strict_kademlia, "\
87                            "gets_succeeded, message) "\
88                            "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'"
89
90 #define INSERT_GENERIC_STAT_STMT "prepare insert_generic_stat from 'INSERT INTO generic_stats" \
91                                  "(trialuid, nodeuid, section, name, value)"\
92                                  "VALUES (@temp_trial, @temp_node, @temp_section, @temp_stat, @temp_value)'"
93
94 #define INSERT_STAT_STMT "prepare insert_stat from 'INSERT INTO node_statistics"\
95                             "(trialuid, nodeuid, route_requests,"\
96                             "route_forwards, result_requests,"\
97                             "client_results, result_forwards, gets,"\
98                             "puts, data_inserts, find_peer_requests, "\
99                             "find_peers_started, gets_started, puts_started, find_peer_responses_received,"\
100                             "get_responses_received, find_peer_responses_sent, get_responses_sent) "\
101                             "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'"
102
103 #define INSERT_DHTKEY_STMT "prepare insert_dhtkey from 'INSERT ignore INTO dhtkeys (dhtkey, trialuid) "\
104                            "VALUES (?, @temp_trial)'"
105
106 #define UPDATE_TRIALS_STMT "prepare update_trial from 'UPDATE trials set endtime= ?, gets_succeeded = ? where trialuid = @temp_trial'"
107
108 #define UPDATE_CONNECTIONS_STMT "prepare update_conn from 'UPDATE trials set totalConnections = ? where trialuid = @temp_trial'"
109
110 #define GET_TRIAL_STMT "prepare select_trial from 'SELECT MAX( trialuid ) FROM trials into @temp_trial'"
111
112 #define GET_TOPOLOGY_STMT "prepare select_topology from 'SELECT MAX( topology_uid ) FROM topology into @temp_topology'"
113
114 #define GET_DHTKEYUID_STMT "prepare get_dhtkeyuid from 'SELECT dhtkeyuid FROM dhtkeys where dhtkey = ? and trialuid = @temp_trial'"
115
116 #define GET_NODEUID_STMT "prepare get_nodeuid from 'SELECT nodeuid FROM nodes where trialuid = @temp_trial and nodeid = ?'"
117
118 #define DATE_STR_SIZE 50
119
120 /**
121  * File to dump all sql statements to.
122  */
123 FILE *outfile;
124
125
126 static char *
127 get_sql_time()
128 {
129   static char date[DATE_STR_SIZE];
130   time_t timetmp;
131   struct tm *tmptr;
132
133   time (&timetmp);
134   memset (date, 0, DATE_STR_SIZE);
135   tmptr = localtime (&timetmp);
136   if (NULL != tmptr)
137     strftime (date, DATE_STR_SIZE, "%Y-%m-%d %H:%M:%S", tmptr);
138   else
139     strcpy (date, "");
140
141   return date;
142 }
143
144 /**
145  * Create a prepared statement.
146  *
147  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
148  */
149 static int
150 prepared_statement_create (const char *statement)
151 {
152   if (fprintf(outfile, "%s;\n", statement) > 0)
153     return GNUNET_OK;
154
155   return GNUNET_SYSERR;
156 }
157
158 /*
159  * Initialize the prepared statements for use with dht test logging
160  */
161 static int
162 iopen ()
163 {
164 #define PINIT(a) (GNUNET_OK != (prepared_statement_create(a)))
165   if (PINIT (INSERT_QUERIES_STMT) ||
166       PINIT (INSERT_ROUTES_STMT) ||
167       PINIT (INSERT_ROUND_STMT) ||
168       PINIT (INSERT_ROUND_DETAILS_STMT) ||
169       PINIT (INSERT_TRIALS_STMT) ||
170       PINIT (SET_MALICIOUS_STMT) ||
171       PINIT (INSERT_GENERIC_STAT_STMT) ||
172       PINIT (INSERT_STAT_STMT) ||
173       PINIT (INSERT_NODES_STMT) ||
174       PINIT (INSERT_DHTKEY_STMT) ||
175       PINIT (UPDATE_TRIALS_STMT) ||
176       PINIT (GET_DHTKEYUID_STMT) ||
177       PINIT (GET_NODEUID_STMT) ||
178       PINIT (UPDATE_CONNECTIONS_STMT) ||
179       PINIT (INSERT_TOPOLOGY_STMT) ||
180       PINIT (EXTEND_TOPOLOGY_STMT) ||
181       PINIT (UPDATE_TOPOLOGY_STMT) ||
182       PINIT (GET_TRIAL_STMT) ||
183       PINIT (GET_TOPOLOGY_STMT))
184     {
185       return GNUNET_SYSERR;
186     }
187 #undef PINIT
188
189   return GNUNET_OK;
190 }
191
192 /*
193  * Inserts the specified round into the dhttests.rounds table
194  *
195  * @param round_type the type of round that is being started
196  * @param round_count counter for the round (if applicable)
197  *
198  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
199  */
200 int add_round (unsigned int round_type, unsigned int round_count)
201 {
202   int ret;
203   if (outfile == NULL)
204     return GNUNET_SYSERR;
205
206   ret = fprintf(outfile, "set @curr_time = \"%s\", @rtype = \"%u\", @rcount = \"%u\";\n", get_sql_time(), round_type, round_count);
207
208   if (ret < 0)
209     return GNUNET_SYSERR;
210   ret = fprintf(outfile, "execute insert_round;\n");
211
212   if (ret >= 0)
213     return GNUNET_OK;
214   return GNUNET_SYSERR;
215 }
216
217 /*
218  * Inserts the specified round results into the
219  * dhttests.processed_round_details table
220  *
221  * @param round_type the type of round that is being started
222  * @param round_count counter for the round (if applicable)
223  * @param num_messages the total number of messages initiated
224  * @param num_messages_succeeded the number of messages that succeeded
225  *
226  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
227  */
228 int add_round_details (unsigned int round_type, unsigned int round_count,
229                        unsigned int num_messages, unsigned int num_messages_succeeded)
230 {
231   int ret;
232   if (outfile == NULL)
233     return GNUNET_SYSERR;
234
235   ret = fprintf(outfile, "set @curr_time = \"%s\", @rtype = \"%u\", @rcount = \"%u\", @totalmsgs = \"%u\", @msgssucceeded = \"%u\";\n",
236                           get_sql_time(), round_type, round_count, num_messages, num_messages_succeeded);
237
238   if (ret < 0)
239     return GNUNET_SYSERR;
240   ret = fprintf(outfile, "execute insert_round_details;\n");
241
242   if (ret >= 0)
243     return GNUNET_OK;
244   return GNUNET_SYSERR;
245 }
246
247 /*
248  * Records the current topology (number of connections, time, trial)
249  *
250  * @param num_connections how many connections are in the topology
251  *
252  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
253  */
254 int
255 add_topology (int num_connections)
256 {
257   int ret;
258   if (outfile == NULL)
259     return GNUNET_SYSERR;
260
261   ret = fprintf(outfile, "set @date = \"%s\", @num = %d;\n", get_sql_time(), num_connections);
262
263   if (ret < 0)
264     return GNUNET_SYSERR;
265   ret = fprintf(outfile, "execute insert_topology using "
266                          "@date, @num;\n");
267   if (ret < 0)
268     return GNUNET_SYSERR;
269
270   ret = fprintf(outfile, "execute select_topology;\n");
271
272   if (ret >= 0)
273     return GNUNET_OK;
274   return GNUNET_SYSERR;
275 }
276
277 /*
278  * Records a connection between two peers in the current topology
279  *
280  * @param first one side of the connection
281  * @param second other side of the connection
282  *
283  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
284  */
285 int
286 add_extended_topology (const struct GNUNET_PeerIdentity *first, const struct GNUNET_PeerIdentity *second)
287 {
288   int ret;
289   if (outfile == NULL)
290     return GNUNET_SYSERR;
291
292   if (first != NULL)
293     ret = fprintf(outfile, "select nodeuid from nodes where trialuid = @temp_trial and nodeid = \"%s\" into @temp_first_node;\n", GNUNET_h2s_full(&first->hashPubKey));
294   else
295     ret = fprintf(outfile, "set @temp_first_node = 0;\n");
296
297   if (ret < 0)
298     return GNUNET_SYSERR;
299
300   if (second != NULL)
301     ret = fprintf(outfile, "select nodeuid from nodes where trialuid = @temp_trial and nodeid = \"%s\" into @temp_second_node;\n", GNUNET_h2s_full(&second->hashPubKey));
302   else
303     ret = fprintf(outfile, "set @temp_second_node = 0;\n");
304
305   if (ret < 0)
306     return GNUNET_SYSERR;
307
308   ret = fprintf(outfile, "execute extend_topology using "
309                          "@temp_first_node, @temp_second_node;\n");
310
311   if (ret >= 0)
312     return GNUNET_OK;
313   return GNUNET_SYSERR;
314 }
315
316
317 /*
318  * Inserts the specified trial into the dhttests.trials table
319  *
320  * @param trial_info struct containing the data to insert about this trial
321  *
322  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
323  */
324 int add_trial (struct GNUNET_DHTLOG_TrialInfo *trial_info)
325 {
326   int ret;
327
328   if (outfile == NULL)
329     return GNUNET_SYSERR;
330
331   ret = fprintf(outfile, "set @date = \"%s\", @oid = %u, @num = %u, @topology = %u, @bl = %u, "
332                    "@connect = %u, @c_t_o = %u, @c_t_o_m = %f, @t_p = %f, "
333                    "@t_pr = %f, @puts = %u, @gets = %u, "
334                    "@concurrent = %u, @settle = %u, @rounds = %u, "
335                    "@m_gets = %u, @m_puts = %u, @m_drops = %u, "
336                    "@m_g_f = %u, @m_p_f = %u, @s_c = %u, @s_f = %u,"
337                    "@s_k = %u, @g_s = %u, @message = \"%s\";\n",
338                    get_sql_time(), trial_info->other_identifier, trial_info->num_nodes, trial_info->topology,
339                    trial_info->blacklist_topology, trial_info->connect_topology,
340                    trial_info->connect_topology_option, trial_info->connect_topology_option_modifier,
341                    trial_info->topology_percentage, trial_info->topology_probability,
342                    trial_info->puts, trial_info->gets, trial_info->concurrent, trial_info->settle_time,
343                    trial_info->num_rounds, trial_info->malicious_getters, trial_info->malicious_putters,
344                    trial_info->malicious_droppers, trial_info->malicious_get_frequency, trial_info->malicious_put_frequency,
345                    trial_info->stop_closest, trial_info->stop_found, trial_info->strict_kademlia, trial_info->gets_succeeded, trial_info->message);
346
347   if (ret < 0)
348     return GNUNET_SYSERR;
349   ret = fprintf(outfile, "execute insert_trial using "
350                          "@date, @oid, @num, @topology, @t_p, @t_pr,"
351                          " @bl, @connect, @c_t_o,"
352                          "@c_t_o_m, @puts, @gets,"
353                          "@concurrent, @settle, @rounds,"
354                          "@m_gets, @m_puts, @m_drops,"
355                          "@m_g_f, @m_p_f, @s_c, @s_f,"
356                          "@s_k, @g_s, @message;\n");
357   if (ret < 0)
358     return GNUNET_SYSERR;
359   ret = fprintf(outfile, "execute select_trial;\n");
360
361   if (ret >= 0)
362     return GNUNET_OK;
363   return GNUNET_SYSERR;
364 }
365
366
367 /*
368  * Inserts the specified stats into the dhttests.generic_stats table
369  *
370  * @param peer the peer inserting the statistic
371  * @param name the name of the statistic
372  * @param section the section of the statistic
373  * @param value the value of the statistic
374  *
375  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
376  */
377 int
378 add_generic_stat (const struct GNUNET_PeerIdentity *peer,
379                   const char *name,
380                   const char *section, uint64_t value)
381 {
382   int ret;
383   if (outfile == NULL)
384     return GNUNET_SYSERR;
385
386   if (peer != NULL)
387     ret = fprintf(outfile, "select nodeuid from nodes where trialuid = @temp_trial and nodeid = \"%s\" into @temp_node;\n", GNUNET_h2s_full(&peer->hashPubKey));
388   else
389     ret = fprintf(outfile, "set @temp_node = 0;\n");
390
391   if (ret < 0)
392     return GNUNET_SYSERR;
393
394   ret = fprintf(outfile, "set @temp_section = \"%s\", @temp_stat = \"%s\", @temp_value = %llu;\n",
395                          section, name, (unsigned long long)value);
396
397   if (ret < 0)
398     return GNUNET_SYSERR;
399
400   ret = fprintf(outfile, "execute insert_generic_stat;\n");
401
402   if (ret < 0)
403     return GNUNET_SYSERR;
404   return GNUNET_OK;
405 }
406
407
408 /*
409  * Inserts the specified stats into the dhttests.node_statistics table
410  *
411  * @param peer the peer inserting the statistic
412  * @param route_requests route requests seen
413  * @param route_forwards route requests forwarded
414  * @param result_requests route result requests seen
415  * @param client_requests client requests initiated
416  * @param result_forwards route results forwarded
417  * @param gets get requests handled
418  * @param puts put requests handle
419  * @param data_inserts data inserted at this node
420  * @param find_peer_requests find peer requests seen
421  * @param find_peers_started find peer requests initiated at this node
422  * @param gets_started get requests initiated at this node
423  * @param puts_started put requests initiated at this node
424  * @param find_peer_responses_received find peer responses received locally
425  * @param get_responses_received get responses received locally
426  * @param find_peer_responses_sent find peer responses sent from this node
427  * @param get_responses_sent get responses sent from this node
428  *
429  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
430  */
431 int
432 add_stat (const struct GNUNET_PeerIdentity *peer, unsigned int route_requests,
433           unsigned int route_forwards, unsigned int result_requests,
434           unsigned int client_requests, unsigned int result_forwards,
435           unsigned int gets, unsigned int puts,
436           unsigned int data_inserts, unsigned int find_peer_requests,
437           unsigned int find_peers_started, unsigned int gets_started,
438           unsigned int puts_started, unsigned int find_peer_responses_received,
439           unsigned int get_responses_received, unsigned int find_peer_responses_sent,
440           unsigned int get_responses_sent)
441 {
442   int ret;
443   if (outfile == NULL)
444     return GNUNET_SYSERR;
445
446   if (peer != NULL)
447     ret = fprintf(outfile, "select nodeuid from nodes where trialuid = @temp_trial and nodeid = \"%s\" into @temp_node;\n", GNUNET_h2s_full(&peer->hashPubKey));
448   else
449     ret = fprintf(outfile, "set @temp_node = 0;\n");
450   if (ret < 0)
451     return GNUNET_SYSERR;
452
453   ret = fprintf(outfile, "set @r_r = %u, @r_f = %u, @res_r = %u, @c_r = %u, "
454                          "@res_f = %u, @gets = %u, @puts = %u, @d_i = %u, "
455                          "@f_p_r = %u, @f_p_s = %u, @g_s = %u, @p_s = %u, "
456                          "@f_p_r_r = %u, @g_r_r = %u, @f_p_r_s = %u, @g_r_s = %u;\n",
457                          route_requests, route_forwards, result_requests,
458                          client_requests, result_forwards, gets, puts,
459                          data_inserts, find_peer_requests, find_peers_started,
460                          gets_started, puts_started, find_peer_responses_received,
461                          get_responses_received, find_peer_responses_sent,
462                          get_responses_sent);
463
464   if (ret < 0)
465     return GNUNET_SYSERR;
466
467   ret = fprintf(outfile, "execute insert_stat using "
468                          "@temp_trial, @temp_node, @r_r, @r_f, @res_r, @c_r, "
469                          "@res_f, @gets, @puts, @d_i, "
470                          "@f_p_r, @f_p_s, @g_s, @p_s, "
471                          "@f_p_r_r, @g_r_r, @f_p_r_s, @g_r_s;\n");
472   if (ret < 0)
473     return GNUNET_SYSERR;
474   return GNUNET_OK;
475 }
476 /*
477  * Inserts the specified dhtkey into the dhttests.dhtkeys table,
478  * stores return value of dhttests.dhtkeys.dhtkeyuid into dhtkeyuid
479  *
480  * @param dhtkeyuid return value
481  * @param dhtkey hashcode of key to insert
482  *
483  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
484  */
485 int
486 add_dhtkey (unsigned long long *dhtkeyuid, const GNUNET_HashCode * dhtkey)
487 {
488   int ret;
489   if (dhtkeyuid != NULL)
490     *dhtkeyuid = 0;
491
492   if (outfile == NULL)
493     return GNUNET_SYSERR;
494
495   if (dhtkey != NULL)
496     ret = fprintf(outfile, "set @dhtkey = \"%s\";\n", GNUNET_h2s_full(dhtkey));
497   else
498     ret = fprintf(outfile, "set @dhtkey = XXXXX;\n");
499
500   if (ret < 0)
501     return GNUNET_SYSERR;
502   ret = fprintf(outfile, "execute insert_dhtkey using @dhtkey;\n");
503
504   if (ret >= 0)
505     return GNUNET_OK;
506   return GNUNET_SYSERR;
507 }
508
509 /*
510  * Inserts the specified node into the dhttests.nodes table
511  *
512  * @param nodeuid the inserted node uid
513  * @param node the node to insert
514  *
515  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
516  */
517 int
518 add_node (unsigned long long *nodeuid, struct GNUNET_PeerIdentity * node)
519 {
520   int ret;
521
522   if (node == NULL)
523     return GNUNET_SYSERR;
524
525   if (outfile == NULL)
526     return GNUNET_SYSERR;
527
528   ret = fprintf(outfile, "set @node = \"%s\";\n", GNUNET_h2s_full(&node->hashPubKey));
529
530   if (ret < 0)
531     return GNUNET_SYSERR;
532
533   ret = fprintf(outfile, "execute insert_node using @node;\n");
534
535   if (ret >= 0)
536     return GNUNET_OK;
537   return GNUNET_SYSERR;
538 }
539
540 /*
541  * Update dhttests.trials table with current server time as end time
542  *
543  * @param gets_succeeded how many gets did the testcase report as successful
544  *
545  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
546  */
547 int
548 update_trials (unsigned int gets_succeeded)
549 {
550   int ret;
551
552   if (outfile == NULL)
553     return GNUNET_SYSERR;
554
555   ret = fprintf(outfile, "set @date = \"%s\", @g_s = %u;\n", get_sql_time(), gets_succeeded);
556
557   if (ret < 0)
558     return GNUNET_SYSERR;
559
560   ret = fprintf(outfile, "execute update_trial using @date, @g_s;\n");
561
562   if (ret >= 0)
563     return GNUNET_OK;
564   else
565     return GNUNET_SYSERR;
566 }
567
568
569 /*
570  * Update dhttests.nodes table setting the identified
571  * node as a malicious dropper.
572  *
573  * @param peer the peer that was set to be malicious
574  *
575  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
576  */
577 int
578 set_malicious (struct GNUNET_PeerIdentity *peer)
579 {
580   int ret;
581
582   if (outfile == NULL)
583     return GNUNET_SYSERR;
584
585   ret = fprintf(outfile, "set @temp_node = \"%s\";\n", GNUNET_h2s_full(&peer->hashPubKey));
586
587   if (ret < 0)
588     return GNUNET_SYSERR;
589
590   ret = fprintf(outfile, "execute set_malicious;\n");
591
592   if (ret >= 0)
593     return GNUNET_OK;
594   else
595     return GNUNET_SYSERR;
596 }
597
598
599 /*
600  * Update dhttests.trials table with total connections information
601  *
602  * @param totalConnections the number of connections
603  *
604  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
605  */
606 int
607 add_connections (unsigned int totalConnections)
608 {
609   int ret;
610
611   if (outfile == NULL)
612     return GNUNET_SYSERR;
613
614   ret = fprintf(outfile, "set @conns = %u;\n", totalConnections);
615
616   if (ret < 0)
617     return GNUNET_SYSERR;
618
619   ret = fprintf(outfile, "execute update_conn using @conns;\n");
620
621   if (ret >= 0)
622     return GNUNET_OK;
623   else
624     return GNUNET_SYSERR;
625 }
626
627
628 /*
629  * Update dhttests.topology table with total connections information
630  *
631  * @param totalConnections the number of connections
632  *
633  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
634  */
635 int
636 update_topology (unsigned int connections)
637 {
638   int ret;
639   if (outfile == NULL)
640     return GNUNET_SYSERR;
641
642   ret = fprintf(outfile, "set @temp_conns = %u;\n", connections);
643
644   if (ret < 0)
645     return GNUNET_SYSERR;
646
647   ret = fprintf(outfile, "execute update_topology using @temp_conns;\n");
648
649   if (ret >= 0)
650     return GNUNET_OK;
651   else
652     return GNUNET_SYSERR;
653 }
654
655 /*
656  * Inserts the specified query into the dhttests.queries table
657  *
658  * @param sqlqueruid inserted query uid
659  * @param queryid dht query id
660  * @param type type of the query
661  * @param hops number of hops query traveled
662  * @param succeeded whether or not query was successful
663  * @param node the node the query hit
664  * @param key the key of the query
665  *
666  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
667  */
668 int
669 add_query (unsigned long long *sqlqueryuid, unsigned long long queryid,
670            unsigned int type, unsigned int hops, int succeeded,
671            const struct GNUNET_PeerIdentity * node, const GNUNET_HashCode * key)
672 {
673   int ret;
674
675   if (outfile == NULL)
676     return GNUNET_SYSERR;
677
678   if (sqlqueryuid != NULL)
679     *sqlqueryuid = 0;
680
681   if (key != NULL)
682     ret = fprintf(outfile, "select dhtkeyuid from dhtkeys where trialuid = @temp_trial and dhtkey = \"%s\" into @temp_dhtkey;\n", GNUNET_h2s_full(key));
683   else
684     ret = fprintf(outfile, "set @temp_dhtkey = 0;\n");
685
686   if (ret < 0)
687     return GNUNET_SYSERR;
688
689   if (node != NULL)
690     ret = fprintf(outfile, "select nodeuid from nodes where trialuid = @temp_trial and nodeid = \"%s\" into @temp_node;\n", GNUNET_h2s_full(&node->hashPubKey));
691   else
692     ret = fprintf(outfile, "set @temp_node = 0;\n");
693
694   if (ret < 0)
695     return GNUNET_SYSERR;
696
697   ret = fprintf(outfile, "set @qid = %llu, @type = %u, @hops = %u, @succ = %d, @time = \"%s\";\n", queryid, type, hops, succeeded, get_sql_time());
698
699   if (ret < 0)
700     return GNUNET_SYSERR;
701
702   ret = fprintf(outfile, "execute insert_query using @type, @hops, @temp_dhtkey, @qid, @succ, @temp_node, @time;\n");
703
704   if (ret >= 0)
705     return GNUNET_OK;
706   else
707     return GNUNET_SYSERR;
708 }
709
710 /*
711  * Inserts the specified route information into the dhttests.routes table
712  *
713  * @param sqlqueruid inserted query uid
714  * @param queryid dht query id
715  * @param type type of the query
716  * @param hops number of hops query traveled
717  * @param succeeded whether or not query was successful
718  * @param node the node the query hit
719  * @param key the key of the query
720  * @param from_node the node that sent the message to node
721  * @param to_node next node to forward message to
722  *
723  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
724  */
725 int
726 add_route (unsigned long long *sqlqueryuid, unsigned long long queryid,
727            unsigned int type, unsigned int hops,
728            int succeeded, const struct GNUNET_PeerIdentity * node,
729            const GNUNET_HashCode * key, const struct GNUNET_PeerIdentity * from_node,
730            const struct GNUNET_PeerIdentity * to_node)
731 {
732   int ret;
733
734   if (outfile == NULL)
735     return GNUNET_SYSERR;
736
737   if (sqlqueryuid != NULL)
738     *sqlqueryuid = 0;
739
740   if (key != NULL)
741     ret = fprintf(outfile, "select dhtkeyuid from dhtkeys where trialuid = @temp_trial and dhtkey = \"%s\" into @temp_dhtkey;\n", GNUNET_h2s_full(key));
742   else
743     ret = fprintf(outfile, "set @temp_dhtkey = 0;\n");
744
745   if (ret < 0)
746     return GNUNET_SYSERR;
747
748   if (node != NULL)
749     ret = fprintf(outfile, "select nodeuid from nodes where trialuid = @temp_trial and nodeid = \"%s\" into @temp_node;\n", GNUNET_h2s_full(&node->hashPubKey));
750   else
751     ret = fprintf(outfile, "set @temp_node = 0;\n");
752
753   if (ret < 0)
754     return GNUNET_SYSERR;
755
756   if (from_node != NULL)
757     ret = fprintf(outfile, "select nodeuid from nodes where trialuid = @temp_trial and nodeid = \"%s\" into @temp_from_node;\n", GNUNET_h2s_full(&from_node->hashPubKey));
758   else
759     ret = fprintf(outfile, "set @temp_from_node = 0;\n");
760
761   if (ret < 0)
762     return GNUNET_SYSERR;
763
764   if (to_node != NULL)
765     ret = fprintf(outfile, "select nodeuid from nodes where trialuid = @temp_trial and nodeid = \"%s\" into @temp_to_node;\n", GNUNET_h2s_full(&to_node->hashPubKey));
766   else
767     ret = fprintf(outfile, "set @temp_to_node = 0;\n");
768
769   if (ret < 0)
770     return GNUNET_SYSERR;
771
772   ret = fprintf(outfile, "set @qid = %llu, @type = %u, @hops = %u, @succ = %d;\n", queryid, type, hops, succeeded);
773
774   if (ret < 0)
775     return GNUNET_SYSERR;
776
777   ret = fprintf(outfile, "execute insert_route using @type, @hops, @temp_dhtkey, @qid, @succ, @temp_node, @temp_from_node, @temp_to_node;\n");
778
779   if (ret >= 0)
780     return GNUNET_OK;
781   else
782     return GNUNET_SYSERR;
783 }
784
785 /*
786  * Provides the dhtlog api
787  *
788  * @param c the configuration to use to connect to a server
789  *
790  * @return the handle to the server, or NULL on error
791  */
792 void *
793 libgnunet_plugin_dhtlog_mysql_dump_init (void * cls)
794 {
795   struct GNUNET_DHTLOG_Plugin *plugin = cls;
796   char *outfile_name;
797   char *outfile_path;
798   char *fn;
799   int dirwarn;
800
801   cfg = plugin->cfg;
802   max_varchar_len = 255;
803
804   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MySQL (DUMP) DHT Logger: initializing\n");
805
806   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
807                                                          "MYSQLDUMP", "PATH",
808                                                          &outfile_path))
809     {
810       outfile_path = GNUNET_strdup("");
811     }
812
813   GNUNET_asprintf (&outfile_name,
814                    "%s%s-%d",
815                    outfile_path,
816                    "mysqldump",
817                    getpid());
818
819   fn = GNUNET_STRINGS_filename_expand (outfile_name);
820
821   if (fn == NULL)
822     {
823       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
824       GNUNET_free(outfile_path);
825       GNUNET_free(outfile_name);
826       return NULL;
827     }
828
829   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
830   outfile = FOPEN (fn, "w");
831
832   if (outfile == NULL)
833     {
834       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
835       if (dirwarn)
836         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
837                     _("Failed to create or access directory for log file `%s'\n"),
838                     fn);
839       GNUNET_free(outfile_path);
840       GNUNET_free(outfile_name);
841       GNUNET_free (fn);
842       return NULL;
843     }
844
845   GNUNET_free (outfile_path);
846   GNUNET_free (outfile_name);
847   GNUNET_free (fn);
848
849   if (iopen () != GNUNET_OK)
850     {
851       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
852                   _("Failed to create file for dhtlog.\n"));
853       fclose (outfile);
854       return NULL;
855     }
856   GNUNET_assert(plugin->dhtlog_api == NULL);
857   plugin->dhtlog_api = GNUNET_malloc(sizeof(struct GNUNET_DHTLOG_Handle));
858   plugin->dhtlog_api->insert_trial = &add_trial;
859   plugin->dhtlog_api->insert_round = &add_round;
860   plugin->dhtlog_api->insert_round_details = &add_round_details;
861   plugin->dhtlog_api->insert_stat = &add_stat;
862   plugin->dhtlog_api->insert_query = &add_query;
863   plugin->dhtlog_api->update_trial = &update_trials;
864   plugin->dhtlog_api->insert_route = &add_route;
865   plugin->dhtlog_api->insert_node = &add_node;
866   plugin->dhtlog_api->insert_dhtkey = &add_dhtkey;
867   plugin->dhtlog_api->update_connections = &add_connections;
868   plugin->dhtlog_api->insert_topology = &add_topology;
869   plugin->dhtlog_api->insert_extended_topology = &add_extended_topology;
870   plugin->dhtlog_api->update_topology = &update_topology;
871   plugin->dhtlog_api->set_malicious = &set_malicious;
872   plugin->dhtlog_api->add_generic_stat = &add_generic_stat;
873
874   return plugin;
875 }
876
877 /**
878  * Shutdown the plugin.
879  */
880 void *
881 libgnunet_plugin_dhtlog_mysql_dump_done (void * cls)
882 {
883   struct GNUNET_DHTLOG_Handle *dhtlog_api = cls;
884   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
885               "MySQL DHT Logger: database shutdown\n");
886   GNUNET_assert(dhtlog_api != NULL);
887
888   GNUNET_free(dhtlog_api);
889   return NULL;
890 }
891
892 /* end of plugin_dhtlog_mysql.c */