diff options
author | Nathan S. Evans <evans@in.tum.de> | 2010-07-20 14:39:30 +0000 |
---|---|---|
committer | Nathan S. Evans <evans@in.tum.de> | 2010-07-20 14:39:30 +0000 |
commit | 429d32f4c389b2dd84aaeaacc8e6e2b9b1ff0a6c (patch) | |
tree | 23e8112223bcad1c57fb9c30d0f1c617d3f3ad18 /src/dht | |
parent | a3513eefb075376ca401fe0dd591f70633b8791b (diff) | |
download | gnunet-429d32f4c389b2dd84aaeaacc8e6e2b9b1ff0a6c.tar.gz gnunet-429d32f4c389b2dd84aaeaacc8e6e2b9b1ff0a6c.zip |
dhtlog plugins
Diffstat (limited to 'src/dht')
-rw-r--r-- | src/dht/plugin_dhtlog_dummy.c | 225 | ||||
-rw-r--r-- | src/dht/plugin_dhtlog_mysql.c | 1191 |
2 files changed, 1416 insertions, 0 deletions
diff --git a/src/dht/plugin_dhtlog_dummy.c b/src/dht/plugin_dhtlog_dummy.c new file mode 100644 index 000000000..6386a6c83 --- /dev/null +++ b/src/dht/plugin_dhtlog_dummy.c | |||
@@ -0,0 +1,225 @@ | |||
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_dummy.c | ||
23 | * @brief Dummy logging plugin to test logging calls | ||
24 | * @author Nathan Evans | ||
25 | * | ||
26 | * Database: NONE | ||
27 | */ | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_util_lib.h" | ||
31 | #include "dhtlog.h" | ||
32 | |||
33 | #define DEBUG_DHTLOG GNUNET_NO | ||
34 | |||
35 | /* | ||
36 | * Inserts the specified trial into the dhttests.trials table | ||
37 | * | ||
38 | * @param trialuid return the trialuid of the newly inserted trial | ||
39 | * @param num_nodes how many nodes are in the trial | ||
40 | * @param topology integer representing topology for this trial | ||
41 | * @param blacklist_topology integer representing blacklist topology for this trial | ||
42 | * @param connect_topology integer representing connect topology for this trial | ||
43 | * @param connect_topology_option integer representing connect topology option | ||
44 | * @param connect_topology_option_modifier float to modify connect option | ||
45 | * @param topology_percentage percentage modifier for certain topologies | ||
46 | * @param topology_probability probability modifier for certain topologies | ||
47 | * @param puts number of puts to perform | ||
48 | * @param gets number of gets to perform | ||
49 | * @param concurrent number of concurrent requests | ||
50 | * @param settle_time time to wait between creating topology and starting testing | ||
51 | * @param num_rounds number of times to repeat the trial | ||
52 | * @param malicious_getters number of malicious GET peers in the trial | ||
53 | * @param malicious_putters number of malicious PUT peers in the trial | ||
54 | * @param malicious_droppers number of malicious DROP peers in the trial | ||
55 | * @param message string to put into DB for this trial | ||
56 | * | ||
57 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure | ||
58 | */ | ||
59 | int | ||
60 | add_trial (unsigned long long *trialuid, int num_nodes, int topology, | ||
61 | int blacklist_topology, int connect_topology, | ||
62 | int connect_topology_option, float connect_topology_option_modifier, | ||
63 | float topology_percentage, float topology_probability, | ||
64 | int puts, int gets, int concurrent, int settle_time, | ||
65 | int num_rounds, int malicious_getters, int malicious_putters, | ||
66 | int malicious_droppers, char *message) | ||
67 | { | ||
68 | *trialuid = 42; | ||
69 | return GNUNET_OK; | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * Inserts the specified dhtkey into the dhttests.dhtkeys table, | ||
74 | * stores return value of dhttests.dhtkeys.dhtkeyuid into dhtkeyuid | ||
75 | * | ||
76 | * @param dhtkeyuid return value | ||
77 | * @param dhtkey hashcode of key to insert | ||
78 | * | ||
79 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure | ||
80 | */ | ||
81 | int | ||
82 | add_dhtkey (unsigned long long *dhtkeyuid, const GNUNET_HashCode * dhtkey) | ||
83 | { | ||
84 | *dhtkeyuid = 1171; | ||
85 | return GNUNET_OK; | ||
86 | } | ||
87 | |||
88 | |||
89 | /* | ||
90 | * Inserts the specified node into the dhttests.nodes table | ||
91 | * | ||
92 | * @param nodeuid the inserted node uid | ||
93 | * @param node the node to insert | ||
94 | * | ||
95 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure | ||
96 | */ | ||
97 | int | ||
98 | add_node (unsigned long long *nodeuid, struct GNUNET_PeerIdentity * node) | ||
99 | { | ||
100 | *nodeuid = 1337; | ||
101 | return GNUNET_OK; | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * Update dhttests.trials table with current server time as end time | ||
106 | * | ||
107 | * @param trialuid trial to update | ||
108 | * @param totalMessagesDropped stats value for messages dropped | ||
109 | * @param totalBytesDropped stats value for total bytes dropped | ||
110 | * @param unknownPeers stats value for unknown peers | ||
111 | * | ||
112 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure. | ||
113 | */ | ||
114 | int | ||
115 | update_trials (unsigned long long trialuid, | ||
116 | unsigned long long totalMessagesDropped, | ||
117 | unsigned long long totalBytesDropped, | ||
118 | unsigned long long unknownPeers) | ||
119 | { | ||
120 | return GNUNET_OK; | ||
121 | } | ||
122 | |||
123 | |||
124 | /* | ||
125 | * Update dhttests.trials table with total connections information | ||
126 | * | ||
127 | * @param trialuid the trialuid to update | ||
128 | * @param totalConnections the number of connections | ||
129 | * | ||
130 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure. | ||
131 | */ | ||
132 | int | ||
133 | add_connections (unsigned long long trialuid, unsigned int totalConnections) | ||
134 | { | ||
135 | return GNUNET_OK; | ||
136 | } | ||
137 | |||
138 | /* | ||
139 | * Inserts the specified query into the dhttests.queries table | ||
140 | * | ||
141 | * @param sqlqueruid inserted query uid | ||
142 | * @param queryid dht query id | ||
143 | * @param type type of the query | ||
144 | * @param hops number of hops query traveled | ||
145 | * @param succeeded whether or not query was successful | ||
146 | * @param node the node the query hit | ||
147 | * @param key the key of the query | ||
148 | * | ||
149 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure. | ||
150 | */ | ||
151 | int | ||
152 | add_query (unsigned long long *sqlqueryuid, unsigned long long queryid, | ||
153 | unsigned int type, unsigned int hops, int succeeded, | ||
154 | const struct GNUNET_PeerIdentity * node, const GNUNET_HashCode * key) | ||
155 | { | ||
156 | *sqlqueryuid = 17; | ||
157 | return GNUNET_OK; | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * Inserts the specified route information into the dhttests.routes table | ||
162 | * | ||
163 | * @param sqlqueruid inserted query uid | ||
164 | * @param queryid dht query id | ||
165 | * @param type type of the query | ||
166 | * @param hops number of hops query traveled | ||
167 | * @param succeeded whether or not query was successful | ||
168 | * @param node the node the query hit | ||
169 | * @param key the key of the query | ||
170 | * @param from_node the node that sent the message to node | ||
171 | * @param to_node next node to forward message to | ||
172 | * | ||
173 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure. | ||
174 | */ | ||
175 | int | ||
176 | add_route (unsigned long long *sqlqueryuid, unsigned long long queryid, | ||
177 | unsigned int type, unsigned int hops, | ||
178 | int succeeded, const struct GNUNET_PeerIdentity * node, | ||
179 | const GNUNET_HashCode * key, const struct GNUNET_PeerIdentity * from_node, | ||
180 | const struct GNUNET_PeerIdentity * to_node) | ||
181 | { | ||
182 | *sqlqueryuid = 18; | ||
183 | return GNUNET_OK; | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * Provides the dhtlog api | ||
188 | * | ||
189 | * @param c the configuration to use to connect to a server | ||
190 | * | ||
191 | * @return the handle to the server, or NULL on error | ||
192 | */ | ||
193 | void * | ||
194 | libgnunet_plugin_dhtlog_dummy_init (void * cls) | ||
195 | { | ||
196 | struct GNUNET_DHTLOG_Plugin *plugin = cls; | ||
197 | #if DEBUG_DHTLOG | ||
198 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "DUMMY DHT Logger: initializing.\n"); | ||
199 | #endif | ||
200 | GNUNET_assert(plugin->dhtlog_api == NULL); | ||
201 | plugin->dhtlog_api = GNUNET_malloc(sizeof(struct GNUNET_DHTLOG_Handle)); | ||
202 | plugin->dhtlog_api->insert_trial = &add_trial; | ||
203 | plugin->dhtlog_api->insert_query = &add_query; | ||
204 | plugin->dhtlog_api->update_trial = &update_trials; | ||
205 | plugin->dhtlog_api->insert_route = &add_route; | ||
206 | plugin->dhtlog_api->insert_node = &add_node; | ||
207 | plugin->dhtlog_api->insert_dhtkey = &add_dhtkey; | ||
208 | plugin->dhtlog_api->update_connections = &add_connections; | ||
209 | return NULL; | ||
210 | } | ||
211 | |||
212 | /** | ||
213 | * Shutdown the module. | ||
214 | */ | ||
215 | void * | ||
216 | libgnunet_plugin_dhtlog_dummy_done (void * cls) | ||
217 | { | ||
218 | #if DEBUG_DHTLOG | ||
219 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
220 | "DUMMY DHT Logger: shutdown\n"); | ||
221 | #endif | ||
222 | return NULL; | ||
223 | } | ||
224 | |||
225 | /* end of plugin_dhtlog_dummy.c */ | ||
diff --git a/src/dht/plugin_dhtlog_mysql.c b/src/dht/plugin_dhtlog_mysql.c new file mode 100644 index 000000000..a67301f83 --- /dev/null +++ b/src/dht/plugin_dhtlog_mysql.c | |||
@@ -0,0 +1,1191 @@ | |||
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.c | ||
23 | * @brief MySQL logging plugin to record DHT operations to MySQL server | ||
24 | * @author Nathan Evans | ||
25 | * | ||
26 | * Database: MySQL | ||
27 | */ | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_util_lib.h" | ||
31 | #include "dhtlog.h" | ||
32 | #include <mysql/mysql.h> | ||
33 | |||
34 | |||
35 | #define DEBUG_DHTLOG GNUNET_NO | ||
36 | |||
37 | /** | ||
38 | * Maximum number of supported parameters for a prepared | ||
39 | * statement. Increase if needed. | ||
40 | */ | ||
41 | #define MAX_PARAM 32 | ||
42 | |||
43 | /** | ||
44 | * A generic statement handle to use | ||
45 | * for prepared statements. This way, | ||
46 | * once the statement is initialized | ||
47 | * we don't redo work. | ||
48 | */ | ||
49 | struct StatementHandle | ||
50 | { | ||
51 | /** | ||
52 | * Internal statement | ||
53 | */ | ||
54 | MYSQL_STMT *statement; | ||
55 | |||
56 | /** | ||
57 | * Textual query | ||
58 | */ | ||
59 | char *query; | ||
60 | |||
61 | /** | ||
62 | * Whether or not the handle is valid | ||
63 | */ | ||
64 | int valid; | ||
65 | }; | ||
66 | |||
67 | /** | ||
68 | * Type of a callback that will be called for each | ||
69 | * data set returned from MySQL. | ||
70 | * | ||
71 | * @param cls user-defined argument | ||
72 | * @param num_values number of elements in values | ||
73 | * @param values values returned by MySQL | ||
74 | * @return GNUNET_OK to continue iterating, GNUNET_SYSERR to abort | ||
75 | */ | ||
76 | typedef int (*GNUNET_MysqlDataProcessor) (void *cls, | ||
77 | unsigned int num_values, | ||
78 | MYSQL_BIND * values); | ||
79 | |||
80 | static unsigned long max_varchar_len; | ||
81 | |||
82 | /** | ||
83 | * The configuration the DHT service is running with | ||
84 | */ | ||
85 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
86 | |||
87 | static unsigned long long current_trial = 0; /* I like to assign 0, just to remember */ | ||
88 | |||
89 | static char *user; | ||
90 | |||
91 | static char *password; | ||
92 | |||
93 | static char *server; | ||
94 | |||
95 | static char *database; | ||
96 | |||
97 | static unsigned long long port; | ||
98 | |||
99 | /** | ||
100 | * Connection to the MySQL Server. | ||
101 | */ | ||
102 | static MYSQL *conn; | ||
103 | |||
104 | #define INSERT_QUERIES_STMT "INSERT INTO queries (trialuid, querytype, hops, dhtkeyuid, dhtqueryid, succeeded, nodeuid) "\ | ||
105 | "VALUES (?, ?, ?, ?, ?, ?, ?)" | ||
106 | static struct StatementHandle *insert_query; | ||
107 | |||
108 | #define INSERT_ROUTES_STMT "INSERT INTO routes (trialuid, querytype, hops, dhtkeyuid, dhtqueryid, succeeded, nodeuid, from_node, to_node) "\ | ||
109 | "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)" | ||
110 | static struct StatementHandle *insert_route; | ||
111 | |||
112 | #define INSERT_NODES_STMT "INSERT INTO nodes (trialuid, nodeid, nodebits) "\ | ||
113 | "VALUES (?, ?, ?)" | ||
114 | static struct StatementHandle *insert_node; | ||
115 | |||
116 | #define INSERT_TRIALS_STMT "INSERT INTO trials"\ | ||
117 | "(starttime, numnodes, topology,"\ | ||
118 | "topology_percentage, topology_probability,"\ | ||
119 | "blacklist_topology, connect_topology, connect_topology_option,"\ | ||
120 | "connect_topology_option_modifier, puts, gets, "\ | ||
121 | "concurrent, settle_time, num_rounds, malicious_getters,"\ | ||
122 | "malicious_putters, malicious_droppers, message) "\ | ||
123 | "VALUES (NOW(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" | ||
124 | |||
125 | static struct StatementHandle *insert_trial; | ||
126 | |||
127 | #define INSERT_DHTKEY_STMT "INSERT INTO dhtkeys (dhtkey, trialuid, keybits) "\ | ||
128 | "VALUES (?, ?, ?)" | ||
129 | static struct StatementHandle *insert_dhtkey; | ||
130 | |||
131 | #define UPDATE_TRIALS_STMT "UPDATE trials set endtime=NOW(), total_messages_dropped = ?, total_bytes_dropped = ?, unknownPeers = ? where trialuid = ?" | ||
132 | static struct StatementHandle *update_trial; | ||
133 | |||
134 | #define UPDATE_CONNECTIONS_STMT "UPDATE trials set totalConnections = ? where trialuid = ?" | ||
135 | static struct StatementHandle *update_connection; | ||
136 | |||
137 | #define GET_TRIAL_STMT "SELECT MAX( trialuid ) FROM trials" | ||
138 | static struct StatementHandle *get_trial; | ||
139 | |||
140 | #define GET_DHTKEYUID_STMT "SELECT dhtkeyuid FROM dhtkeys where dhtkey = ? and trialuid = ?" | ||
141 | static struct StatementHandle *get_dhtkeyuid; | ||
142 | |||
143 | #define GET_NODEUID_STMT "SELECT nodeuid FROM nodes where trialuid = ? and nodeid = ?" | ||
144 | static struct StatementHandle *get_nodeuid; | ||
145 | |||
146 | /** | ||
147 | * Run a query (not a select statement) | ||
148 | * | ||
149 | * @return GNUNET_OK if executed, GNUNET_SYSERR if an error occurred | ||
150 | */ | ||
151 | int | ||
152 | run_statement (const char *statement) | ||
153 | { | ||
154 | mysql_query (conn, statement); | ||
155 | if (mysql_error (conn)[0]) | ||
156 | { | ||
157 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
158 | "mysql_query"); | ||
159 | return GNUNET_SYSERR; | ||
160 | } | ||
161 | return GNUNET_OK; | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * Creates tables if they don't already exist for dht logging | ||
166 | */ | ||
167 | static int | ||
168 | itable () | ||
169 | { | ||
170 | #define MRUNS(a) (GNUNET_OK != run_statement (a) ) | ||
171 | |||
172 | if (MRUNS ("CREATE TABLE IF NOT EXISTS `dhtkeys` (" | ||
173 | "dhtkeyuid int(10) unsigned NOT NULL auto_increment COMMENT 'Unique Key given to each query'," | ||
174 | "`dhtkey` varchar(255) NOT NULL COMMENT 'The ASCII value of the key being searched for'," | ||
175 | "trialuid int(10) unsigned NOT NULL," | ||
176 | "keybits blob NOT NULL," | ||
177 | "UNIQUE KEY `dhtkeyuid` (`dhtkeyuid`)" | ||
178 | ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1")) | ||
179 | return GNUNET_SYSERR; | ||
180 | |||
181 | if (MRUNS ("CREATE TABLE IF NOT EXISTS `nodes` (" | ||
182 | "`nodeuid` int(10) unsigned NOT NULL auto_increment," | ||
183 | "`trialuid` int(10) unsigned NOT NULL," | ||
184 | "`nodeid` varchar(255) NOT NULL," | ||
185 | "`nodebits` blob NOT NULL," | ||
186 | "PRIMARY KEY (`nodeuid`)" | ||
187 | ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1")) | ||
188 | return GNUNET_SYSERR; | ||
189 | |||
190 | if (MRUNS ("CREATE TABLE IF NOT EXISTS `queries` (" | ||
191 | "`trialuid` int(10) unsigned NOT NULL," | ||
192 | "`queryuid` int(10) unsigned NOT NULL auto_increment," | ||
193 | "`dhtqueryid` bigint(20) NOT NULL," | ||
194 | "`querytype` enum('1','2','3','4','5') NOT NULL," | ||
195 | "`hops` int(10) unsigned NOT NULL," | ||
196 | "`succeeded` tinyint NOT NULL," | ||
197 | "`nodeuid` int(10) unsigned NOT NULL," | ||
198 | "`time` timestamp NOT NULL default CURRENT_TIMESTAMP," | ||
199 | "`dhtkeyuid` int(10) unsigned NOT NULL," | ||
200 | "PRIMARY KEY (`queryuid`)" | ||
201 | ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1")) | ||
202 | return GNUNET_SYSERR; | ||
203 | |||
204 | if (MRUNS ("CREATE TABLE IF NOT EXISTS `routes` (" | ||
205 | "`trialuid` int(10) unsigned NOT NULL," | ||
206 | "`queryuid` int(10) unsigned NOT NULL auto_increment," | ||
207 | "`dhtqueryid` bigint(20) NOT NULL," | ||
208 | "`querytype` enum('1','2','3','4','5') NOT NULL," | ||
209 | "`hops` int(10) unsigned NOT NULL," | ||
210 | "`succeeded` tinyint NOT NULL," | ||
211 | "`nodeuid` int(10) unsigned NOT NULL," | ||
212 | "`time` timestamp NOT NULL default CURRENT_TIMESTAMP," | ||
213 | "`dhtkeyuid` int(10) unsigned NOT NULL," | ||
214 | "`from_node` int(10) unsigned NOT NULL," | ||
215 | "`to_node` int(10) unsigned NOT NULL," | ||
216 | "PRIMARY KEY (`queryuid`)" | ||
217 | ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1")) | ||
218 | return GNUNET_SYSERR; | ||
219 | |||
220 | if (MRUNS ("CREATE TABLE IF NOT EXISTS `trials` (" | ||
221 | "`trialuid` int(10) unsigned NOT NULL auto_increment," | ||
222 | "`numnodes` int(10) unsigned NOT NULL," | ||
223 | "`topology` int(10) NOT NULL," | ||
224 | "`starttime` datetime NOT NULL," | ||
225 | "`endtime` datetime NOT NULL," | ||
226 | "`puts` int(10) unsigned NOT NULL," | ||
227 | "`gets` int(10) unsigned NOT NULL," | ||
228 | "`concurrent` int(10) unsigned NOT NULL," | ||
229 | "`settle_time` int(10) unsigned NOT NULL," | ||
230 | "`totalConnections` int(10) unsigned NOT NULL," | ||
231 | "`message` text NOT NULL," | ||
232 | "`num_rounds` int(10) unsigned NOT NULL," | ||
233 | "`malicious_getters` int(10) unsigned NOT NULL," | ||
234 | "`malicious_putters` int(10) unsigned NOT NULL," | ||
235 | "`malicious_droppers` int(10) unsigned NOT NULL," | ||
236 | "`totalMessagesDropped` int(10) unsigned NOT NULL," | ||
237 | "`totalBytesDropped` int(10) unsigned NOT NULL," | ||
238 | "`topology_modifier` double NOT NULL," | ||
239 | "`logNMultiplier` double NOT NULL," | ||
240 | "`maxnetbps` bigint(20) unsigned NOT NULL," | ||
241 | "`unknownPeers` int(10) unsigned NOT NULL," | ||
242 | "PRIMARY KEY (`trialuid`)," | ||
243 | "UNIQUE KEY `trialuid` (`trialuid`)" | ||
244 | ") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1")) | ||
245 | return GNUNET_SYSERR; | ||
246 | |||
247 | if (MRUNS ("SET AUTOCOMMIT = 1")) | ||
248 | return GNUNET_SYSERR; | ||
249 | |||
250 | return GNUNET_OK; | ||
251 | #undef MRUNS | ||
252 | } | ||
253 | |||
254 | /** | ||
255 | * Create a prepared statement. | ||
256 | * | ||
257 | * @return NULL on error | ||
258 | */ | ||
259 | struct StatementHandle * | ||
260 | prepared_statement_create (const char *statement) | ||
261 | { | ||
262 | struct StatementHandle *ret; | ||
263 | |||
264 | ret = GNUNET_malloc (sizeof (struct StatementHandle)); | ||
265 | ret->query = GNUNET_strdup (statement); | ||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | /** | ||
270 | * Create a prepared statement. | ||
271 | * | ||
272 | * @return NULL on error | ||
273 | */ | ||
274 | void | ||
275 | prepared_statement_close (struct StatementHandle *s) | ||
276 | { | ||
277 | if (s == NULL) | ||
278 | return; | ||
279 | |||
280 | if (s->query != NULL) | ||
281 | GNUNET_free(s->query); | ||
282 | if (s->valid == GNUNET_YES) | ||
283 | mysql_stmt_close(s->statement); | ||
284 | GNUNET_free(s); | ||
285 | } | ||
286 | |||
287 | /* | ||
288 | * Initialize the prepared statements for use with dht test logging | ||
289 | */ | ||
290 | static int | ||
291 | iopen () | ||
292 | { | ||
293 | int ret; | ||
294 | |||
295 | conn = mysql_init (NULL); | ||
296 | if (conn == NULL) | ||
297 | return GNUNET_SYSERR; | ||
298 | |||
299 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to mysql with: user %s, pass %s, server %s, database %s, port %d\n", | ||
300 | user, password, server, database, port); | ||
301 | |||
302 | mysql_real_connect (conn, server, user, password, | ||
303 | database, (unsigned int) port, NULL, 0); | ||
304 | |||
305 | if (mysql_error (conn)[0]) | ||
306 | { | ||
307 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
308 | "mysql_real_connect"); | ||
309 | return GNUNET_SYSERR; | ||
310 | } | ||
311 | |||
312 | #if OLD | ||
313 | db = GNUNET_MYSQL_database_open (coreAPI->ectx, coreAPI->cfg); | ||
314 | if (db == NULL) | ||
315 | return GNUNET_SYSERR; | ||
316 | #endif | ||
317 | |||
318 | ret = itable (); | ||
319 | |||
320 | #define PINIT(a,b) (NULL == (a = prepared_statement_create(b))) | ||
321 | if (PINIT (insert_query, INSERT_QUERIES_STMT) || | ||
322 | PINIT (insert_route, INSERT_ROUTES_STMT) || | ||
323 | PINIT (insert_trial, INSERT_TRIALS_STMT) || | ||
324 | PINIT (insert_node, INSERT_NODES_STMT) || | ||
325 | PINIT (insert_dhtkey, INSERT_DHTKEY_STMT) || | ||
326 | PINIT (update_trial, UPDATE_TRIALS_STMT) || | ||
327 | PINIT (get_dhtkeyuid, GET_DHTKEYUID_STMT) || | ||
328 | PINIT (get_nodeuid, GET_NODEUID_STMT) || | ||
329 | PINIT (update_connection, UPDATE_CONNECTIONS_STMT) || | ||
330 | PINIT (get_trial, GET_TRIAL_STMT)) | ||
331 | { | ||
332 | return GNUNET_SYSERR; | ||
333 | } | ||
334 | #undef PINIT | ||
335 | |||
336 | return ret; | ||
337 | } | ||
338 | |||
339 | static int | ||
340 | return_ok (void *cls, unsigned int num_values, MYSQL_BIND * values) | ||
341 | { | ||
342 | return GNUNET_OK; | ||
343 | } | ||
344 | |||
345 | /** | ||
346 | * Prepare a statement for running. | ||
347 | * | ||
348 | * @return GNUNET_OK on success | ||
349 | */ | ||
350 | static int | ||
351 | prepare_statement (struct StatementHandle *ret) | ||
352 | { | ||
353 | if (GNUNET_YES == ret->valid) | ||
354 | return GNUNET_OK; | ||
355 | |||
356 | ret->statement = mysql_stmt_init (conn); | ||
357 | if (ret->statement == NULL) | ||
358 | return GNUNET_SYSERR; | ||
359 | |||
360 | if (mysql_stmt_prepare (ret->statement, ret->query, strlen (ret->query))) | ||
361 | { | ||
362 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
363 | "mysql_stmt_prepare `%s', %s", ret->query, mysql_error(conn)); | ||
364 | mysql_stmt_close (ret->statement); | ||
365 | ret->statement = NULL; | ||
366 | return GNUNET_SYSERR; | ||
367 | } | ||
368 | ret->valid = GNUNET_YES; | ||
369 | return GNUNET_OK; | ||
370 | } | ||
371 | |||
372 | /** | ||
373 | * Bind the parameters for the given MySQL statement | ||
374 | * and run it. | ||
375 | * | ||
376 | * @param s statement to bind and run | ||
377 | * @param ap arguments for the binding | ||
378 | * @return GNUNET_SYSERR on error, GNUNET_OK on success | ||
379 | */ | ||
380 | static int | ||
381 | init_params (struct StatementHandle *s, va_list ap) | ||
382 | { | ||
383 | MYSQL_BIND qbind[MAX_PARAM]; | ||
384 | unsigned int pc; | ||
385 | unsigned int off; | ||
386 | enum enum_field_types ft; | ||
387 | |||
388 | pc = mysql_stmt_param_count (s->statement); | ||
389 | if (pc > MAX_PARAM) | ||
390 | { | ||
391 | /* increase internal constant! */ | ||
392 | GNUNET_break (0); | ||
393 | return GNUNET_SYSERR; | ||
394 | } | ||
395 | memset (qbind, 0, sizeof (qbind)); | ||
396 | off = 0; | ||
397 | ft = 0; | ||
398 | while ((pc > 0) && (-1 != (ft = va_arg (ap, enum enum_field_types)))) | ||
399 | { | ||
400 | qbind[off].buffer_type = ft; | ||
401 | switch (ft) | ||
402 | { | ||
403 | case MYSQL_TYPE_FLOAT: | ||
404 | qbind[off].buffer = va_arg (ap, float *); | ||
405 | break; | ||
406 | case MYSQL_TYPE_LONGLONG: | ||
407 | qbind[off].buffer = va_arg (ap, unsigned long long *); | ||
408 | qbind[off].is_unsigned = va_arg (ap, int); | ||
409 | break; | ||
410 | case MYSQL_TYPE_LONG: | ||
411 | qbind[off].buffer = va_arg (ap, unsigned int *); | ||
412 | qbind[off].is_unsigned = va_arg (ap, int); | ||
413 | break; | ||
414 | case MYSQL_TYPE_VAR_STRING: | ||
415 | case MYSQL_TYPE_STRING: | ||
416 | case MYSQL_TYPE_BLOB: | ||
417 | qbind[off].buffer = va_arg (ap, void *); | ||
418 | qbind[off].buffer_length = va_arg (ap, unsigned long); | ||
419 | qbind[off].length = va_arg (ap, unsigned long *); | ||
420 | break; | ||
421 | default: | ||
422 | /* unsupported type */ | ||
423 | GNUNET_break (0); | ||
424 | return GNUNET_SYSERR; | ||
425 | } | ||
426 | pc--; | ||
427 | off++; | ||
428 | } | ||
429 | if (!((pc == 0) && (ft != -1) && (va_arg (ap, int) == -1))) | ||
430 | { | ||
431 | GNUNET_break (0); | ||
432 | return GNUNET_SYSERR; | ||
433 | } | ||
434 | if (mysql_stmt_bind_param (s->statement, qbind)) | ||
435 | { | ||
436 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
437 | _("`%s' failed at %s:%d with error: %s\n"), | ||
438 | "mysql_stmt_bind_param", | ||
439 | __FILE__, __LINE__, mysql_stmt_error (s->statement)); | ||
440 | return GNUNET_SYSERR; | ||
441 | } | ||
442 | |||
443 | if (mysql_stmt_execute (s->statement)) | ||
444 | { | ||
445 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
446 | _("`%s' failed at %s:%d with error: %s\n"), | ||
447 | "mysql_stmt_execute", | ||
448 | __FILE__, __LINE__, mysql_stmt_error (s->statement)); | ||
449 | return GNUNET_SYSERR; | ||
450 | } | ||
451 | |||
452 | return GNUNET_OK; | ||
453 | } | ||
454 | |||
455 | /** | ||
456 | * Run a prepared SELECT statement. | ||
457 | * | ||
458 | * @param result_size number of elements in results array | ||
459 | * @param results pointer to already initialized MYSQL_BIND | ||
460 | * array (of sufficient size) for passing results | ||
461 | * @param processor function to call on each result | ||
462 | * @param processor_cls extra argument to processor | ||
463 | * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective | ||
464 | * values (size + buffer-reference for pointers); terminated | ||
465 | * with "-1" | ||
466 | * @return GNUNET_SYSERR on error, otherwise | ||
467 | * the number of successfully affected (or queried) rows | ||
468 | */ | ||
469 | int | ||
470 | prepared_statement_run_select (struct StatementHandle | ||
471 | *s, unsigned int result_size, | ||
472 | MYSQL_BIND * results, | ||
473 | GNUNET_MysqlDataProcessor | ||
474 | processor, void *processor_cls, | ||
475 | ...) | ||
476 | { | ||
477 | va_list ap; | ||
478 | int ret; | ||
479 | unsigned int rsize; | ||
480 | int total; | ||
481 | |||
482 | if (GNUNET_OK != prepare_statement (s)) | ||
483 | { | ||
484 | GNUNET_break (0); | ||
485 | return GNUNET_SYSERR; | ||
486 | } | ||
487 | va_start (ap, processor_cls); | ||
488 | if (GNUNET_OK != init_params (s, ap)) | ||
489 | { | ||
490 | GNUNET_break (0); | ||
491 | va_end (ap); | ||
492 | return GNUNET_SYSERR; | ||
493 | } | ||
494 | va_end (ap); | ||
495 | rsize = mysql_stmt_field_count (s->statement); | ||
496 | if (rsize > result_size) | ||
497 | { | ||
498 | GNUNET_break (0); | ||
499 | return GNUNET_SYSERR; | ||
500 | } | ||
501 | if (mysql_stmt_bind_result (s->statement, results)) | ||
502 | { | ||
503 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
504 | _("`%s' failed at %s:%d with error: %s\n"), | ||
505 | "mysql_stmt_bind_result", | ||
506 | __FILE__, __LINE__, mysql_stmt_error (s->statement)); | ||
507 | return GNUNET_SYSERR; | ||
508 | } | ||
509 | |||
510 | total = 0; | ||
511 | while (1) | ||
512 | { | ||
513 | ret = mysql_stmt_fetch (s->statement); | ||
514 | if (ret == MYSQL_NO_DATA) | ||
515 | break; | ||
516 | if (ret != 0) | ||
517 | { | ||
518 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
519 | _("`%s' failed at %s:%d with error: %s\n"), | ||
520 | "mysql_stmt_fetch", | ||
521 | __FILE__, __LINE__, mysql_stmt_error (s->statement)); | ||
522 | return GNUNET_SYSERR; | ||
523 | } | ||
524 | if (processor != NULL) | ||
525 | if (GNUNET_OK != processor (processor_cls, rsize, results)) | ||
526 | break; | ||
527 | total++; | ||
528 | } | ||
529 | mysql_stmt_reset (s->statement); | ||
530 | return total; | ||
531 | } | ||
532 | |||
533 | static int | ||
534 | get_current_trial (unsigned long long *trialuid) | ||
535 | { | ||
536 | MYSQL_BIND rbind[1]; | ||
537 | |||
538 | memset (rbind, 0, sizeof (rbind)); | ||
539 | rbind[0].buffer_type = MYSQL_TYPE_LONG; | ||
540 | rbind[0].is_unsigned = 1; | ||
541 | rbind[0].buffer = trialuid; | ||
542 | |||
543 | if ((GNUNET_OK != | ||
544 | prepared_statement_run_select (get_trial, | ||
545 | 1, | ||
546 | rbind, | ||
547 | return_ok, NULL, -1))) | ||
548 | { | ||
549 | return GNUNET_SYSERR; | ||
550 | } | ||
551 | |||
552 | return GNUNET_OK; | ||
553 | } | ||
554 | |||
555 | |||
556 | /** | ||
557 | * Run a prepared statement that does NOT produce results. | ||
558 | * | ||
559 | * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective | ||
560 | * values (size + buffer-reference for pointers); terminated | ||
561 | * with "-1" | ||
562 | * @param insert_id NULL or address where to store the row ID of whatever | ||
563 | * was inserted (only for INSERT statements!) | ||
564 | * @return GNUNET_SYSERR on error, otherwise | ||
565 | * the number of successfully affected rows | ||
566 | */ | ||
567 | int | ||
568 | prepared_statement_run (struct StatementHandle *s, | ||
569 | unsigned long long *insert_id, ...) | ||
570 | { | ||
571 | va_list ap; | ||
572 | int affected; | ||
573 | |||
574 | if (GNUNET_OK != prepare_statement(s)) | ||
575 | { | ||
576 | GNUNET_break(0); | ||
577 | return GNUNET_SYSERR; | ||
578 | } | ||
579 | GNUNET_assert(s->valid == GNUNET_YES); | ||
580 | if (s->statement == NULL) | ||
581 | return GNUNET_SYSERR; | ||
582 | |||
583 | va_start (ap, insert_id); | ||
584 | |||
585 | if (mysql_stmt_prepare (s->statement, s->query, strlen (s->query))) | ||
586 | { | ||
587 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "mysql_stmt_prepare ERROR"); | ||
588 | return GNUNET_SYSERR; | ||
589 | } | ||
590 | |||
591 | if (GNUNET_OK != init_params (s, ap)) | ||
592 | { | ||
593 | va_end (ap); | ||
594 | return GNUNET_SYSERR; | ||
595 | } | ||
596 | |||
597 | va_end (ap); | ||
598 | affected = mysql_stmt_affected_rows (s->statement); | ||
599 | if (NULL != insert_id) | ||
600 | *insert_id = (unsigned long long) mysql_stmt_insert_id (s->statement); | ||
601 | mysql_stmt_reset (s->statement); | ||
602 | |||
603 | return affected; | ||
604 | } | ||
605 | |||
606 | /* | ||
607 | * Inserts the specified trial into the dhttests.trials table | ||
608 | * | ||
609 | * FIXME: Update sql tables, then this functions | ||
610 | * parameters accordingly. | ||
611 | */ | ||
612 | int | ||
613 | add_trial (unsigned long long *trialuid, int num_nodes, int topology, | ||
614 | int blacklist_topology, int connect_topology, | ||
615 | int connect_topology_option, float connect_topology_option_modifier, | ||
616 | float topology_percentage, float topology_probability, | ||
617 | int puts, int gets, int concurrent, int settle_time, | ||
618 | int num_rounds, int malicious_getters, int malicious_putters, | ||
619 | int malicious_droppers, char *message) | ||
620 | { | ||
621 | MYSQL_STMT *stmt; | ||
622 | int ret; | ||
623 | unsigned long long m_len; | ||
624 | m_len = strlen (message); | ||
625 | |||
626 | stmt = mysql_stmt_init(conn); | ||
627 | if (GNUNET_OK != | ||
628 | (ret = prepared_statement_run (insert_trial, | ||
629 | trialuid, | ||
630 | MYSQL_TYPE_LONG, | ||
631 | &num_nodes, | ||
632 | GNUNET_YES, | ||
633 | MYSQL_TYPE_LONG, | ||
634 | &topology, | ||
635 | GNUNET_YES, | ||
636 | MYSQL_TYPE_FLOAT, | ||
637 | &topology_percentage, | ||
638 | MYSQL_TYPE_FLOAT, | ||
639 | &topology_probability, | ||
640 | MYSQL_TYPE_LONG, | ||
641 | &blacklist_topology, | ||
642 | GNUNET_YES, | ||
643 | MYSQL_TYPE_LONG, | ||
644 | &connect_topology, | ||
645 | GNUNET_YES, | ||
646 | MYSQL_TYPE_LONG, | ||
647 | &connect_topology_option, | ||
648 | GNUNET_YES, | ||
649 | MYSQL_TYPE_FLOAT, | ||
650 | &connect_topology_option_modifier, | ||
651 | MYSQL_TYPE_LONG, | ||
652 | &puts, | ||
653 | GNUNET_YES, | ||
654 | MYSQL_TYPE_LONG, | ||
655 | &gets, | ||
656 | GNUNET_YES, | ||
657 | MYSQL_TYPE_LONG, | ||
658 | &concurrent, | ||
659 | GNUNET_YES, | ||
660 | MYSQL_TYPE_LONG, | ||
661 | &settle_time, | ||
662 | GNUNET_YES, | ||
663 | MYSQL_TYPE_LONG, | ||
664 | &num_rounds, | ||
665 | GNUNET_YES, | ||
666 | MYSQL_TYPE_LONG, | ||
667 | &malicious_getters, | ||
668 | GNUNET_YES, | ||
669 | MYSQL_TYPE_LONG, | ||
670 | &malicious_putters, | ||
671 | GNUNET_YES, | ||
672 | MYSQL_TYPE_LONG, | ||
673 | &malicious_droppers, | ||
674 | GNUNET_YES, | ||
675 | MYSQL_TYPE_BLOB, | ||
676 | message, | ||
677 | max_varchar_len + | ||
678 | max_varchar_len, &m_len, | ||
679 | -1))) | ||
680 | { | ||
681 | if (ret == GNUNET_SYSERR) | ||
682 | { | ||
683 | mysql_stmt_close(stmt); | ||
684 | return GNUNET_SYSERR; | ||
685 | } | ||
686 | } | ||
687 | |||
688 | get_current_trial (¤t_trial); | ||
689 | #if DEBUG_DHTLOG | ||
690 | fprintf (stderr, "Current trial is %llu\n", current_trial); | ||
691 | #endif | ||
692 | mysql_stmt_close(stmt); | ||
693 | return GNUNET_OK; | ||
694 | } | ||
695 | |||
696 | static int | ||
697 | get_dhtkey_uid (unsigned long long *dhtkeyuid, const GNUNET_HashCode * key) | ||
698 | { | ||
699 | MYSQL_BIND rbind[1]; | ||
700 | struct GNUNET_CRYPTO_HashAsciiEncoded encKey; | ||
701 | unsigned long long k_len; | ||
702 | memset (rbind, 0, sizeof (rbind)); | ||
703 | rbind[0].buffer_type = MYSQL_TYPE_LONG; | ||
704 | rbind[0].is_unsigned = 1; | ||
705 | rbind[0].buffer = dhtkeyuid; | ||
706 | GNUNET_CRYPTO_hash_to_enc (key, &encKey); | ||
707 | k_len = strlen ((char *) &encKey); | ||
708 | |||
709 | if ((GNUNET_OK != | ||
710 | prepared_statement_run_select (get_dhtkeyuid, | ||
711 | 1, | ||
712 | rbind, | ||
713 | return_ok, NULL, | ||
714 | MYSQL_TYPE_VAR_STRING, | ||
715 | &encKey, | ||
716 | max_varchar_len, | ||
717 | &k_len, | ||
718 | MYSQL_TYPE_LONGLONG, | ||
719 | ¤t_trial, | ||
720 | GNUNET_YES, -1))) | ||
721 | { | ||
722 | return GNUNET_SYSERR; | ||
723 | } | ||
724 | |||
725 | return GNUNET_OK; | ||
726 | } | ||
727 | |||
728 | /* | ||
729 | * Inserts the specified dhtkey into the dhttests.dhtkeys table, | ||
730 | * stores return value of dhttests.dhtkeys.dhtkeyuid into dhtkeyuid | ||
731 | */ | ||
732 | int | ||
733 | add_dhtkey (unsigned long long *dhtkeyuid, const GNUNET_HashCode * dhtkey) | ||
734 | { | ||
735 | |||
736 | int ret; | ||
737 | struct GNUNET_CRYPTO_HashAsciiEncoded encKey; | ||
738 | unsigned long long k_len; | ||
739 | unsigned long long h_len; | ||
740 | unsigned long long curr_dhtkeyuid; | ||
741 | GNUNET_CRYPTO_hash_to_enc (dhtkey, &encKey); | ||
742 | k_len = strlen ((char *) &encKey); | ||
743 | h_len = sizeof (GNUNET_HashCode); | ||
744 | curr_dhtkeyuid = 0; | ||
745 | ret = get_dhtkey_uid(&curr_dhtkeyuid, dhtkey); | ||
746 | if (curr_dhtkeyuid != 0) /* dhtkey already exists */ | ||
747 | { | ||
748 | if (dhtkeyuid != NULL) | ||
749 | *dhtkeyuid = curr_dhtkeyuid; | ||
750 | return GNUNET_OK; | ||
751 | } | ||
752 | |||
753 | if (GNUNET_OK != | ||
754 | (ret = prepared_statement_run (insert_dhtkey, | ||
755 | dhtkeyuid, | ||
756 | MYSQL_TYPE_VAR_STRING, | ||
757 | &encKey, | ||
758 | max_varchar_len, | ||
759 | &k_len, | ||
760 | MYSQL_TYPE_LONG, | ||
761 | ¤t_trial, | ||
762 | GNUNET_YES, | ||
763 | MYSQL_TYPE_BLOB, | ||
764 | dhtkey, | ||
765 | sizeof (GNUNET_HashCode), | ||
766 | &h_len, -1))) | ||
767 | { | ||
768 | if (ret == GNUNET_SYSERR) | ||
769 | { | ||
770 | return GNUNET_SYSERR; | ||
771 | } | ||
772 | } | ||
773 | |||
774 | return GNUNET_OK; | ||
775 | } | ||
776 | |||
777 | |||
778 | static int | ||
779 | get_node_uid (unsigned long long *nodeuid, const GNUNET_HashCode * peerHash) | ||
780 | { | ||
781 | MYSQL_BIND rbind[1]; | ||
782 | struct GNUNET_CRYPTO_HashAsciiEncoded encPeer; | ||
783 | unsigned long long p_len; | ||
784 | |||
785 | int ret; | ||
786 | memset (rbind, 0, sizeof (rbind)); | ||
787 | rbind[0].buffer_type = MYSQL_TYPE_LONG; | ||
788 | rbind[0].buffer = nodeuid; | ||
789 | rbind[0].is_unsigned = GNUNET_YES; | ||
790 | |||
791 | GNUNET_CRYPTO_hash_to_enc (peerHash, &encPeer); | ||
792 | p_len = strlen ((char *) &encPeer); | ||
793 | |||
794 | if (1 != (ret = prepared_statement_run_select (get_nodeuid, | ||
795 | 1, | ||
796 | rbind, | ||
797 | return_ok, | ||
798 | NULL, | ||
799 | MYSQL_TYPE_LONG, | ||
800 | ¤t_trial, | ||
801 | GNUNET_YES, | ||
802 | MYSQL_TYPE_VAR_STRING, | ||
803 | &encPeer, | ||
804 | max_varchar_len, | ||
805 | &p_len, -1))) | ||
806 | { | ||
807 | #if DEBUG_DHTLOG | ||
808 | fprintf (stderr, "FAILED\n"); | ||
809 | #endif | ||
810 | return GNUNET_SYSERR; | ||
811 | } | ||
812 | return GNUNET_OK; | ||
813 | } | ||
814 | |||
815 | |||
816 | /* | ||
817 | * Inserts the specified node into the dhttests.nodes table | ||
818 | */ | ||
819 | int | ||
820 | add_node (unsigned long long *nodeuid, struct GNUNET_PeerIdentity * node) | ||
821 | { | ||
822 | struct GNUNET_CRYPTO_HashAsciiEncoded encPeer; | ||
823 | unsigned long p_len; | ||
824 | unsigned long h_len; | ||
825 | int ret; | ||
826 | |||
827 | if (node == NULL) | ||
828 | return GNUNET_SYSERR; | ||
829 | |||
830 | GNUNET_CRYPTO_hash_to_enc (&node->hashPubKey, &encPeer); | ||
831 | p_len = (unsigned long) strlen ((char *) &encPeer); | ||
832 | h_len = sizeof (GNUNET_HashCode); | ||
833 | if (GNUNET_OK != | ||
834 | (ret = prepared_statement_run (insert_node, | ||
835 | nodeuid, | ||
836 | MYSQL_TYPE_LONGLONG, | ||
837 | ¤t_trial, | ||
838 | GNUNET_YES, | ||
839 | MYSQL_TYPE_VAR_STRING, | ||
840 | &encPeer, | ||
841 | max_varchar_len, | ||
842 | &p_len, | ||
843 | MYSQL_TYPE_BLOB, | ||
844 | &node->hashPubKey, | ||
845 | sizeof (GNUNET_HashCode), | ||
846 | &h_len, -1))) | ||
847 | { | ||
848 | if (ret == GNUNET_SYSERR) | ||
849 | { | ||
850 | return GNUNET_SYSERR; | ||
851 | } | ||
852 | } | ||
853 | return GNUNET_OK; | ||
854 | } | ||
855 | |||
856 | /* | ||
857 | * Update dhttests.trials table with current server time as end time | ||
858 | */ | ||
859 | int | ||
860 | update_trials (unsigned long long trialuid, | ||
861 | unsigned long long totalMessagesDropped, | ||
862 | unsigned long long totalBytesDropped, | ||
863 | unsigned long long unknownPeers) | ||
864 | { | ||
865 | int ret; | ||
866 | #if DEBUG_DHTLOG | ||
867 | if (trialuid != current_trial) | ||
868 | { | ||
869 | fprintf (stderr, | ||
870 | _("Trialuid to update is not equal to current_trial\n")); | ||
871 | } | ||
872 | #endif | ||
873 | if (GNUNET_OK != | ||
874 | (ret = prepared_statement_run (update_trial, | ||
875 | NULL, | ||
876 | MYSQL_TYPE_LONGLONG, | ||
877 | &totalMessagesDropped, | ||
878 | GNUNET_YES, | ||
879 | MYSQL_TYPE_LONGLONG, | ||
880 | &totalBytesDropped, | ||
881 | GNUNET_YES, | ||
882 | MYSQL_TYPE_LONGLONG, | ||
883 | &unknownPeers, | ||
884 | GNUNET_YES, | ||
885 | MYSQL_TYPE_LONGLONG, | ||
886 | &trialuid, GNUNET_YES, -1))) | ||
887 | { | ||
888 | if (ret == GNUNET_SYSERR) | ||
889 | { | ||
890 | return GNUNET_SYSERR; | ||
891 | } | ||
892 | } | ||
893 | if (ret > 0) | ||
894 | return GNUNET_OK; | ||
895 | else | ||
896 | return GNUNET_SYSERR; | ||
897 | } | ||
898 | |||
899 | |||
900 | /* | ||
901 | * Update dhttests.trials table with total connections information | ||
902 | */ | ||
903 | int | ||
904 | add_connections (unsigned long long trialuid, unsigned int totalConnections) | ||
905 | { | ||
906 | int ret; | ||
907 | #if DEBUG_DHTLOG | ||
908 | if (trialuid != current_trial) | ||
909 | { | ||
910 | fprintf (stderr, | ||
911 | _("Trialuid to update is not equal to current_trial(!)(?)\n")); | ||
912 | } | ||
913 | #endif | ||
914 | if (GNUNET_OK != | ||
915 | (ret = prepared_statement_run (update_connection, | ||
916 | NULL, | ||
917 | MYSQL_TYPE_LONG, | ||
918 | &totalConnections, | ||
919 | GNUNET_YES, | ||
920 | MYSQL_TYPE_LONGLONG, | ||
921 | &trialuid, GNUNET_YES, -1))) | ||
922 | { | ||
923 | if (ret == GNUNET_SYSERR) | ||
924 | { | ||
925 | return GNUNET_SYSERR; | ||
926 | } | ||
927 | } | ||
928 | if (ret > 0) | ||
929 | return GNUNET_OK; | ||
930 | else | ||
931 | return GNUNET_SYSERR; | ||
932 | } | ||
933 | |||
934 | /* | ||
935 | * Inserts the specified query into the dhttests.queries table | ||
936 | */ | ||
937 | int | ||
938 | add_query (unsigned long long *sqlqueryuid, unsigned long long queryid, | ||
939 | unsigned int type, unsigned int hops, int succeeded, | ||
940 | const struct GNUNET_PeerIdentity * node, const GNUNET_HashCode * key) | ||
941 | { | ||
942 | int ret; | ||
943 | unsigned long long peer_uid, key_uid; | ||
944 | peer_uid = 0; | ||
945 | key_uid = 0; | ||
946 | |||
947 | if ((node != NULL) | ||
948 | && (GNUNET_OK == get_node_uid (&peer_uid, &node->hashPubKey))) | ||
949 | { | ||
950 | |||
951 | } | ||
952 | else | ||
953 | { | ||
954 | return GNUNET_SYSERR; | ||
955 | } | ||
956 | |||
957 | if ((key != NULL) && (GNUNET_OK == get_dhtkey_uid (&key_uid, key))) | ||
958 | { | ||
959 | |||
960 | } | ||
961 | else if ((key != NULL) && (key->bits[(512 / 8 / sizeof (unsigned int)) - 1] == 42)) /* Malicious marker */ | ||
962 | { | ||
963 | key_uid = 0; | ||
964 | } | ||
965 | else | ||
966 | { | ||
967 | return GNUNET_SYSERR; | ||
968 | } | ||
969 | |||
970 | if (GNUNET_OK != | ||
971 | (ret = prepared_statement_run (insert_query, | ||
972 | sqlqueryuid, | ||
973 | MYSQL_TYPE_LONGLONG, | ||
974 | ¤t_trial, | ||
975 | GNUNET_YES, | ||
976 | MYSQL_TYPE_LONG, | ||
977 | &type, | ||
978 | GNUNET_NO, | ||
979 | MYSQL_TYPE_LONG, | ||
980 | &hops, | ||
981 | GNUNET_YES, | ||
982 | MYSQL_TYPE_LONGLONG, | ||
983 | &key_uid, | ||
984 | GNUNET_YES, | ||
985 | MYSQL_TYPE_LONGLONG, | ||
986 | &queryid, | ||
987 | GNUNET_YES, | ||
988 | MYSQL_TYPE_LONG, | ||
989 | &succeeded, | ||
990 | GNUNET_NO, | ||
991 | MYSQL_TYPE_LONGLONG, | ||
992 | &peer_uid, GNUNET_YES, -1))) | ||
993 | { | ||
994 | if (ret == GNUNET_SYSERR) | ||
995 | { | ||
996 | return GNUNET_SYSERR; | ||
997 | } | ||
998 | } | ||
999 | if (ret > 0) | ||
1000 | return GNUNET_OK; | ||
1001 | else | ||
1002 | return GNUNET_SYSERR; | ||
1003 | } | ||
1004 | |||
1005 | /* | ||
1006 | * Inserts the specified route information into the dhttests.routes table | ||
1007 | */ | ||
1008 | int | ||
1009 | add_route (unsigned long long *sqlqueryuid, unsigned long long queryid, | ||
1010 | unsigned int type, unsigned int hops, | ||
1011 | int succeeded, const struct GNUNET_PeerIdentity * node, | ||
1012 | const GNUNET_HashCode * key, const struct GNUNET_PeerIdentity * from_node, | ||
1013 | const struct GNUNET_PeerIdentity * to_node) | ||
1014 | { | ||
1015 | unsigned long long peer_uid = 0; | ||
1016 | unsigned long long key_uid = 0; | ||
1017 | unsigned long long from_uid = 0; | ||
1018 | unsigned long long to_uid = 0; | ||
1019 | int ret; | ||
1020 | |||
1021 | if (from_node != NULL) | ||
1022 | get_node_uid (&from_uid, &from_node->hashPubKey); | ||
1023 | else | ||
1024 | from_uid = 0; | ||
1025 | |||
1026 | if (to_node != NULL) | ||
1027 | get_node_uid (&to_uid, &to_node->hashPubKey); | ||
1028 | else | ||
1029 | to_uid = 0; | ||
1030 | |||
1031 | if ((node != NULL)) | ||
1032 | { | ||
1033 | if (1 != get_node_uid (&peer_uid, &node->hashPubKey)) | ||
1034 | { | ||
1035 | return GNUNET_SYSERR; | ||
1036 | } | ||
1037 | } | ||
1038 | else | ||
1039 | return GNUNET_SYSERR; | ||
1040 | |||
1041 | if ((key != NULL)) | ||
1042 | { | ||
1043 | if (1 != get_dhtkey_uid (&key_uid, key)) | ||
1044 | { | ||
1045 | return GNUNET_SYSERR; | ||
1046 | } | ||
1047 | } | ||
1048 | else | ||
1049 | return GNUNET_SYSERR; | ||
1050 | |||
1051 | if (GNUNET_OK != | ||
1052 | (ret = prepared_statement_run (insert_route, | ||
1053 | sqlqueryuid, | ||
1054 | MYSQL_TYPE_LONGLONG, | ||
1055 | ¤t_trial, | ||
1056 | GNUNET_YES, | ||
1057 | MYSQL_TYPE_LONG, | ||
1058 | &type, | ||
1059 | GNUNET_NO, | ||
1060 | MYSQL_TYPE_LONG, | ||
1061 | &hops, | ||
1062 | GNUNET_YES, | ||
1063 | MYSQL_TYPE_LONGLONG, | ||
1064 | &key_uid, | ||
1065 | GNUNET_YES, | ||
1066 | MYSQL_TYPE_LONGLONG, | ||
1067 | &queryid, | ||
1068 | GNUNET_YES, | ||
1069 | MYSQL_TYPE_LONG, | ||
1070 | &succeeded, | ||
1071 | GNUNET_NO, | ||
1072 | MYSQL_TYPE_LONGLONG, | ||
1073 | &peer_uid, | ||
1074 | GNUNET_YES, | ||
1075 | MYSQL_TYPE_LONGLONG, | ||
1076 | &from_uid, | ||
1077 | GNUNET_YES, | ||
1078 | MYSQL_TYPE_LONGLONG, | ||
1079 | &to_uid, GNUNET_YES, -1))) | ||
1080 | { | ||
1081 | if (ret == GNUNET_SYSERR) | ||
1082 | { | ||
1083 | return GNUNET_SYSERR; | ||
1084 | } | ||
1085 | } | ||
1086 | if (ret > 0) | ||
1087 | return GNUNET_OK; | ||
1088 | else | ||
1089 | return GNUNET_SYSERR; | ||
1090 | } | ||
1091 | |||
1092 | /* | ||
1093 | * Provides the dhtlog api | ||
1094 | * | ||
1095 | * @param c the configuration to use to connect to a server | ||
1096 | * | ||
1097 | * @return the handle to the server, or NULL on error | ||
1098 | */ | ||
1099 | void * | ||
1100 | libgnunet_plugin_dhtlog_mysql_init (void * cls) | ||
1101 | { | ||
1102 | struct GNUNET_DHTLOG_Plugin *plugin = cls; | ||
1103 | |||
1104 | cfg = plugin->cfg; | ||
1105 | max_varchar_len = 255; | ||
1106 | #if DEBUG_DHTLOG | ||
1107 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MySQL DHT Logger: initializing database\n"); | ||
1108 | #endif | ||
1109 | |||
1110 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg, | ||
1111 | "MYSQL", "DATABASE", | ||
1112 | &database)) | ||
1113 | { | ||
1114 | database = GNUNET_strdup("gnunet"); | ||
1115 | } | ||
1116 | |||
1117 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg, | ||
1118 | "MYSQL", "USER", &user)) | ||
1119 | { | ||
1120 | user = GNUNET_strdup("dht"); | ||
1121 | } | ||
1122 | |||
1123 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg, | ||
1124 | "MYSQL", "PASSWORD", &password)) | ||
1125 | { | ||
1126 | password = GNUNET_strdup("dhttest**"); | ||
1127 | } | ||
1128 | |||
1129 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg, | ||
1130 | "MYSQL", "SERVER", &server)) | ||
1131 | { | ||
1132 | server = GNUNET_strdup("localhost"); | ||
1133 | } | ||
1134 | |||
1135 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (plugin->cfg, | ||
1136 | "MYSQL", "MYSQL_PORT", &port)) | ||
1137 | { | ||
1138 | port = 0; | ||
1139 | } | ||
1140 | |||
1141 | if (iopen () != GNUNET_OK) | ||
1142 | { | ||
1143 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1144 | _("Failed to initialize MySQL database connection for dhtlog.\n")); | ||
1145 | return NULL; | ||
1146 | } | ||
1147 | GNUNET_assert(plugin->dhtlog_api == NULL); | ||
1148 | plugin->dhtlog_api = GNUNET_malloc(sizeof(struct GNUNET_DHTLOG_Handle)); | ||
1149 | plugin->dhtlog_api->insert_trial = &add_trial; | ||
1150 | plugin->dhtlog_api->insert_query = &add_query; | ||
1151 | plugin->dhtlog_api->update_trial = &update_trials; | ||
1152 | plugin->dhtlog_api->insert_route = &add_route; | ||
1153 | plugin->dhtlog_api->insert_node = &add_node; | ||
1154 | plugin->dhtlog_api->insert_dhtkey = &add_dhtkey; | ||
1155 | plugin->dhtlog_api->update_connections = &add_connections; | ||
1156 | get_current_trial (¤t_trial); | ||
1157 | |||
1158 | return NULL; | ||
1159 | } | ||
1160 | |||
1161 | /** | ||
1162 | * Shutdown the module. | ||
1163 | */ | ||
1164 | void * | ||
1165 | libgnunet_plugin_dhtlog_mysql_done (void * cls) | ||
1166 | { | ||
1167 | struct GNUNET_DHTLOG_Handle *dhtlog_api = cls; | ||
1168 | #if DEBUG_DHTLOG | ||
1169 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1170 | "MySQL DHT Logger: database shutdown\n"); | ||
1171 | #endif | ||
1172 | GNUNET_assert(dhtlog_api != NULL); | ||
1173 | prepared_statement_close(insert_query); | ||
1174 | prepared_statement_close(insert_route); | ||
1175 | prepared_statement_close(insert_trial); | ||
1176 | prepared_statement_close(insert_node); | ||
1177 | prepared_statement_close(insert_dhtkey); | ||
1178 | prepared_statement_close(update_trial); | ||
1179 | prepared_statement_close(get_dhtkeyuid); | ||
1180 | prepared_statement_close(get_nodeuid); | ||
1181 | prepared_statement_close(update_connection); | ||
1182 | prepared_statement_close(get_trial); | ||
1183 | |||
1184 | if (conn != NULL) | ||
1185 | mysql_close (conn); | ||
1186 | |||
1187 | GNUNET_free(dhtlog_api); | ||
1188 | return NULL; | ||
1189 | } | ||
1190 | |||
1191 | /* end of plugin_dhtlog_mysql.c */ | ||