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