aboutsummaryrefslogtreecommitdiff
path: root/src/namecache/plugin_namecache_postgres.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/namecache/plugin_namecache_postgres.c')
-rw-r--r--src/namecache/plugin_namecache_postgres.c291
1 files changed, 148 insertions, 143 deletions
diff --git a/src/namecache/plugin_namecache_postgres.c b/src/namecache/plugin_namecache_postgres.c
index 6d0e4e918..e4b360ef2 100644
--- a/src/namecache/plugin_namecache_postgres.c
+++ b/src/namecache/plugin_namecache_postgres.c
@@ -31,13 +31,14 @@
31#include "namecache.h" 31#include "namecache.h"
32 32
33 33
34#define LOG(kind, ...) GNUNET_log_from(kind, "namecache-postgres", __VA_ARGS__) 34#define LOG(kind, ...) GNUNET_log_from (kind, "namecache-postgres", __VA_ARGS__)
35 35
36 36
37/** 37/**
38 * Context for all functions in this plugin. 38 * Context for all functions in this plugin.
39 */ 39 */
40struct Plugin { 40struct Plugin
41{
41 const struct GNUNET_CONFIGURATION_Handle *cfg; 42 const struct GNUNET_CONFIGURATION_Handle *cfg;
42 43
43 /** 44 /**
@@ -56,81 +57,85 @@ struct Plugin {
56 * @return #GNUNET_OK on success 57 * @return #GNUNET_OK on success
57 */ 58 */
58static int 59static int
59database_setup(struct Plugin *plugin) 60database_setup (struct Plugin *plugin)
60{ 61{
61 struct GNUNET_PQ_ExecuteStatement es_temporary = 62 struct GNUNET_PQ_ExecuteStatement es_temporary =
62 GNUNET_PQ_make_execute("CREATE TEMPORARY TABLE IF NOT EXISTS ns096blocks (" 63 GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS ns096blocks ("
63 " query BYTEA NOT NULL DEFAULT ''," 64 " query BYTEA NOT NULL DEFAULT '',"
64 " block BYTEA NOT NULL DEFAULT ''," 65 " block BYTEA NOT NULL DEFAULT '',"
65 " expiration_time BIGINT NOT NULL DEFAULT 0" 66 " expiration_time BIGINT NOT NULL DEFAULT 0"
66 ")" 67 ")"
67 "WITH OIDS"); 68 "WITH OIDS");
68 struct GNUNET_PQ_ExecuteStatement es_default = 69 struct GNUNET_PQ_ExecuteStatement es_default =
69 GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS ns096blocks (" 70 GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS ns096blocks ("
70 " query BYTEA NOT NULL DEFAULT ''," 71 " query BYTEA NOT NULL DEFAULT '',"
71 " block BYTEA NOT NULL DEFAULT ''," 72 " block BYTEA NOT NULL DEFAULT '',"
72 " expiration_time BIGINT NOT NULL DEFAULT 0" 73 " expiration_time BIGINT NOT NULL DEFAULT 0"
73 ")" 74 ")"
74 "WITH OIDS"); 75 "WITH OIDS");
75 const struct GNUNET_PQ_ExecuteStatement *cr; 76 const struct GNUNET_PQ_ExecuteStatement *cr;
76 77
77 plugin->dbh = GNUNET_PQ_connect_with_cfg(plugin->cfg, 78 plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->cfg,
78 "namecache-postgres"); 79 "namecache-postgres");
79 if (NULL == plugin->dbh) 80 if (NULL == plugin->dbh)
80 return GNUNET_SYSERR; 81 return GNUNET_SYSERR;
81 if (GNUNET_YES == 82 if (GNUNET_YES ==
82 GNUNET_CONFIGURATION_get_value_yesno(plugin->cfg, 83 GNUNET_CONFIGURATION_get_value_yesno (plugin->cfg,
83 "namecache-postgres", 84 "namecache-postgres",
84 "TEMPORARY_TABLE")) 85 "TEMPORARY_TABLE"))
85 { 86 {
86 cr = &es_temporary; 87 cr = &es_temporary;
87 } 88 }
88 else 89 else
89 { 90 {
90 cr = &es_default; 91 cr = &es_default;
91 } 92 }
92 93
93 { 94 {
94 struct GNUNET_PQ_ExecuteStatement es[] = { 95 struct GNUNET_PQ_ExecuteStatement es[] = {
95 *cr, 96 *cr,
96 GNUNET_PQ_make_try_execute("CREATE INDEX ir_query_hash ON ns096blocks (query,expiration_time)"), 97 GNUNET_PQ_make_try_execute (
97 GNUNET_PQ_make_try_execute("CREATE INDEX ir_block_expiration ON ns096blocks (expiration_time)"), 98 "CREATE INDEX ir_query_hash ON ns096blocks (query,expiration_time)"),
99 GNUNET_PQ_make_try_execute (
100 "CREATE INDEX ir_block_expiration ON ns096blocks (expiration_time)"),
98 GNUNET_PQ_EXECUTE_STATEMENT_END 101 GNUNET_PQ_EXECUTE_STATEMENT_END
99 }; 102 };
100 103
101 if (GNUNET_OK != 104 if (GNUNET_OK !=
102 GNUNET_PQ_exec_statements(plugin->dbh, 105 GNUNET_PQ_exec_statements (plugin->dbh,
103 es)) 106 es))
104 { 107 {
105 PQfinish(plugin->dbh); 108 PQfinish (plugin->dbh);
106 plugin->dbh = NULL; 109 plugin->dbh = NULL;
107 return GNUNET_SYSERR; 110 return GNUNET_SYSERR;
108 } 111 }
109 } 112 }
110 113
111 { 114 {
112 struct GNUNET_PQ_PreparedStatement ps[] = { 115 struct GNUNET_PQ_PreparedStatement ps[] = {
113 GNUNET_PQ_make_prepare("cache_block", 116 GNUNET_PQ_make_prepare ("cache_block",
114 "INSERT INTO ns096blocks (query, block, expiration_time) VALUES " 117 "INSERT INTO ns096blocks (query, block, expiration_time) VALUES "
115 "($1, $2, $3)", 3), 118 "($1, $2, $3)", 3),
116 GNUNET_PQ_make_prepare("expire_blocks", 119 GNUNET_PQ_make_prepare ("expire_blocks",
117 "DELETE FROM ns096blocks WHERE expiration_time<$1", 1), 120 "DELETE FROM ns096blocks WHERE expiration_time<$1",
118 GNUNET_PQ_make_prepare("delete_block", 121 1),
119 "DELETE FROM ns096blocks WHERE query=$1 AND expiration_time<=$2", 2), 122 GNUNET_PQ_make_prepare ("delete_block",
120 GNUNET_PQ_make_prepare("lookup_block", 123 "DELETE FROM ns096blocks WHERE query=$1 AND expiration_time<=$2",
121 "SELECT block FROM ns096blocks WHERE query=$1" 124 2),
122 " ORDER BY expiration_time DESC LIMIT 1", 1), 125 GNUNET_PQ_make_prepare ("lookup_block",
126 "SELECT block FROM ns096blocks WHERE query=$1"
127 " ORDER BY expiration_time DESC LIMIT 1", 1),
123 GNUNET_PQ_PREPARED_STATEMENT_END 128 GNUNET_PQ_PREPARED_STATEMENT_END
124 }; 129 };
125 130
126 if (GNUNET_OK != 131 if (GNUNET_OK !=
127 GNUNET_PQ_prepare_statements(plugin->dbh, 132 GNUNET_PQ_prepare_statements (plugin->dbh,
128 ps)) 133 ps))
129 { 134 {
130 PQfinish(plugin->dbh); 135 PQfinish (plugin->dbh);
131 plugin->dbh = NULL; 136 plugin->dbh = NULL;
132 return GNUNET_SYSERR; 137 return GNUNET_SYSERR;
133 } 138 }
134 } 139 }
135 140
136 return GNUNET_OK; 141 return GNUNET_OK;
@@ -143,19 +148,19 @@ database_setup(struct Plugin *plugin)
143 * @param plugin the plugin 148 * @param plugin the plugin
144 */ 149 */
145static void 150static void
146namecache_postgres_expire_blocks(struct Plugin *plugin) 151namecache_postgres_expire_blocks (struct Plugin *plugin)
147{ 152{
148 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get(); 153 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
149 struct GNUNET_PQ_QueryParam params[] = { 154 struct GNUNET_PQ_QueryParam params[] = {
150 GNUNET_PQ_query_param_absolute_time(&now), 155 GNUNET_PQ_query_param_absolute_time (&now),
151 GNUNET_PQ_query_param_end 156 GNUNET_PQ_query_param_end
152 }; 157 };
153 enum GNUNET_DB_QueryStatus res; 158 enum GNUNET_DB_QueryStatus res;
154 159
155 res = GNUNET_PQ_eval_prepared_non_select(plugin->dbh, 160 res = GNUNET_PQ_eval_prepared_non_select (plugin->dbh,
156 "expire_blocks", 161 "expire_blocks",
157 params); 162 params);
158 GNUNET_break(GNUNET_DB_STATUS_HARD_ERROR != res); 163 GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != res);
159} 164}
160 165
161 166
@@ -167,21 +172,21 @@ namecache_postgres_expire_blocks(struct Plugin *plugin)
167 * @param expiration_time how old does the block have to be for deletion 172 * @param expiration_time how old does the block have to be for deletion
168 */ 173 */
169static void 174static void
170delete_old_block(struct Plugin *plugin, 175delete_old_block (struct Plugin *plugin,
171 const struct GNUNET_HashCode *query, 176 const struct GNUNET_HashCode *query,
172 struct GNUNET_TIME_AbsoluteNBO expiration_time) 177 struct GNUNET_TIME_AbsoluteNBO expiration_time)
173{ 178{
174 struct GNUNET_PQ_QueryParam params[] = { 179 struct GNUNET_PQ_QueryParam params[] = {
175 GNUNET_PQ_query_param_auto_from_type(query), 180 GNUNET_PQ_query_param_auto_from_type (query),
176 GNUNET_PQ_query_param_absolute_time_nbo(&expiration_time), 181 GNUNET_PQ_query_param_absolute_time_nbo (&expiration_time),
177 GNUNET_PQ_query_param_end 182 GNUNET_PQ_query_param_end
178 }; 183 };
179 enum GNUNET_DB_QueryStatus res; 184 enum GNUNET_DB_QueryStatus res;
180 185
181 res = GNUNET_PQ_eval_prepared_non_select(plugin->dbh, 186 res = GNUNET_PQ_eval_prepared_non_select (plugin->dbh,
182 "delete_block", 187 "delete_block",
183 params); 188 params);
184 GNUNET_break(GNUNET_DB_STATUS_HARD_ERROR != res); 189 GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != res);
185} 190}
186 191
187 192
@@ -193,38 +198,38 @@ delete_old_block(struct Plugin *plugin,
193 * @return #GNUNET_OK on success, else #GNUNET_SYSERR 198 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
194 */ 199 */
195static int 200static int
196namecache_postgres_cache_block(void *cls, 201namecache_postgres_cache_block (void *cls,
197 const struct GNUNET_GNSRECORD_Block *block) 202 const struct GNUNET_GNSRECORD_Block *block)
198{ 203{
199 struct Plugin *plugin = cls; 204 struct Plugin *plugin = cls;
200 struct GNUNET_HashCode query; 205 struct GNUNET_HashCode query;
201 size_t block_size = ntohl(block->purpose.size) + 206 size_t block_size = ntohl (block->purpose.size)
202 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) + 207 + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)
203 sizeof(struct GNUNET_CRYPTO_EcdsaSignature); 208 + sizeof(struct GNUNET_CRYPTO_EcdsaSignature);
204 struct GNUNET_PQ_QueryParam params[] = { 209 struct GNUNET_PQ_QueryParam params[] = {
205 GNUNET_PQ_query_param_auto_from_type(&query), 210 GNUNET_PQ_query_param_auto_from_type (&query),
206 GNUNET_PQ_query_param_fixed_size(block, block_size), 211 GNUNET_PQ_query_param_fixed_size (block, block_size),
207 GNUNET_PQ_query_param_absolute_time_nbo(&block->expiration_time), 212 GNUNET_PQ_query_param_absolute_time_nbo (&block->expiration_time),
208 GNUNET_PQ_query_param_end 213 GNUNET_PQ_query_param_end
209 }; 214 };
210 enum GNUNET_DB_QueryStatus res; 215 enum GNUNET_DB_QueryStatus res;
211 216
212 namecache_postgres_expire_blocks(plugin); 217 namecache_postgres_expire_blocks (plugin);
213 GNUNET_CRYPTO_hash(&block->derived_key, 218 GNUNET_CRYPTO_hash (&block->derived_key,
214 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), 219 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
215 &query); 220 &query);
216 if (block_size > 64 * 65536) 221 if (block_size > 64 * 65536)
217 { 222 {
218 GNUNET_break(0); 223 GNUNET_break (0);
219 return GNUNET_SYSERR; 224 return GNUNET_SYSERR;
220 } 225 }
221 delete_old_block(plugin, 226 delete_old_block (plugin,
222 &query, 227 &query,
223 block->expiration_time); 228 block->expiration_time);
224 229
225 res = GNUNET_PQ_eval_prepared_non_select(plugin->dbh, 230 res = GNUNET_PQ_eval_prepared_non_select (plugin->dbh,
226 "cache_block", 231 "cache_block",
227 params); 232 params);
228 if (0 > res) 233 if (0 > res)
229 return GNUNET_SYSERR; 234 return GNUNET_SYSERR;
230 return GNUNET_OK; 235 return GNUNET_OK;
@@ -242,57 +247,57 @@ namecache_postgres_cache_block(void *cls,
242 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error 247 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
243 */ 248 */
244static int 249static int
245namecache_postgres_lookup_block(void *cls, 250namecache_postgres_lookup_block (void *cls,
246 const struct GNUNET_HashCode *query, 251 const struct GNUNET_HashCode *query,
247 GNUNET_NAMECACHE_BlockCallback iter, 252 GNUNET_NAMECACHE_BlockCallback iter,
248 void *iter_cls) 253 void *iter_cls)
249{ 254{
250 struct Plugin *plugin = cls; 255 struct Plugin *plugin = cls;
251 size_t bsize; 256 size_t bsize;
252 struct GNUNET_GNSRECORD_Block *block; 257 struct GNUNET_GNSRECORD_Block *block;
253 struct GNUNET_PQ_QueryParam params[] = { 258 struct GNUNET_PQ_QueryParam params[] = {
254 GNUNET_PQ_query_param_auto_from_type(query), 259 GNUNET_PQ_query_param_auto_from_type (query),
255 GNUNET_PQ_query_param_end 260 GNUNET_PQ_query_param_end
256 }; 261 };
257 struct GNUNET_PQ_ResultSpec rs[] = { 262 struct GNUNET_PQ_ResultSpec rs[] = {
258 GNUNET_PQ_result_spec_variable_size("block", 263 GNUNET_PQ_result_spec_variable_size ("block",
259 (void **)&block, 264 (void **) &block,
260 &bsize), 265 &bsize),
261 GNUNET_PQ_result_spec_end 266 GNUNET_PQ_result_spec_end
262 }; 267 };
263 enum GNUNET_DB_QueryStatus res; 268 enum GNUNET_DB_QueryStatus res;
264 269
265 res = GNUNET_PQ_eval_prepared_singleton_select(plugin->dbh, 270 res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh,
266 "lookup_block", 271 "lookup_block",
267 params, 272 params,
268 rs); 273 rs);
269 if (0 > res) 274 if (0 > res)
270 { 275 {
271 LOG(GNUNET_ERROR_TYPE_WARNING, 276 LOG (GNUNET_ERROR_TYPE_WARNING,
272 "Failing lookup block in namecache (postgres error)\n"); 277 "Failing lookup block in namecache (postgres error)\n");
273 return GNUNET_SYSERR; 278 return GNUNET_SYSERR;
274 } 279 }
275 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == res) 280 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == res)
276 { 281 {
277 /* no result */ 282 /* no result */
278 LOG(GNUNET_ERROR_TYPE_DEBUG, 283 LOG (GNUNET_ERROR_TYPE_DEBUG,
279 "Ending iteration (no more results)\n"); 284 "Ending iteration (no more results)\n");
280 return GNUNET_NO; 285 return GNUNET_NO;
281 } 286 }
282 if ((bsize < sizeof(*block)) || 287 if ((bsize < sizeof(*block)) ||
283 (bsize != ntohl(block->purpose.size) + 288 (bsize != ntohl (block->purpose.size)
284 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) + 289 + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)
285 sizeof(struct GNUNET_CRYPTO_EcdsaSignature))) 290 + sizeof(struct GNUNET_CRYPTO_EcdsaSignature)))
286 { 291 {
287 GNUNET_break(0); 292 GNUNET_break (0);
288 LOG(GNUNET_ERROR_TYPE_DEBUG, 293 LOG (GNUNET_ERROR_TYPE_DEBUG,
289 "Failing lookup (corrupt block)\n"); 294 "Failing lookup (corrupt block)\n");
290 GNUNET_PQ_cleanup_result(rs); 295 GNUNET_PQ_cleanup_result (rs);
291 return GNUNET_SYSERR; 296 return GNUNET_SYSERR;
292 } 297 }
293 iter(iter_cls, 298 iter (iter_cls,
294 block); 299 block);
295 GNUNET_PQ_cleanup_result(rs); 300 GNUNET_PQ_cleanup_result (rs);
296 return GNUNET_OK; 301 return GNUNET_OK;
297} 302}
298 303
@@ -304,9 +309,9 @@ namecache_postgres_lookup_block(void *cls,
304 * @param plugin the plugin context (state for this module) 309 * @param plugin the plugin context (state for this module)
305 */ 310 */
306static void 311static void
307database_shutdown(struct Plugin *plugin) 312database_shutdown (struct Plugin *plugin)
308{ 313{
309 PQfinish(plugin->dbh); 314 PQfinish (plugin->dbh);
310 plugin->dbh = NULL; 315 plugin->dbh = NULL;
311} 316}
312 317
@@ -318,7 +323,7 @@ database_shutdown(struct Plugin *plugin)
318 * @return NULL on error, otherwise the plugin context 323 * @return NULL on error, otherwise the plugin context
319 */ 324 */
320void * 325void *
321libgnunet_plugin_namecache_postgres_init(void *cls) 326libgnunet_plugin_namecache_postgres_init (void *cls)
322{ 327{
323 static struct Plugin plugin; 328 static struct Plugin plugin;
324 const struct GNUNET_CONFIGURATION_Handle *cfg = cls; 329 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
@@ -326,19 +331,19 @@ libgnunet_plugin_namecache_postgres_init(void *cls)
326 331
327 if (NULL != plugin.cfg) 332 if (NULL != plugin.cfg)
328 return NULL; /* can only initialize once! */ 333 return NULL; /* can only initialize once! */
329 memset(&plugin, 0, sizeof(struct Plugin)); 334 memset (&plugin, 0, sizeof(struct Plugin));
330 plugin.cfg = cfg; 335 plugin.cfg = cfg;
331 if (GNUNET_OK != database_setup(&plugin)) 336 if (GNUNET_OK != database_setup (&plugin))
332 { 337 {
333 database_shutdown(&plugin); 338 database_shutdown (&plugin);
334 return NULL; 339 return NULL;
335 } 340 }
336 api = GNUNET_new(struct GNUNET_NAMECACHE_PluginFunctions); 341 api = GNUNET_new (struct GNUNET_NAMECACHE_PluginFunctions);
337 api->cls = &plugin; 342 api->cls = &plugin;
338 api->cache_block = &namecache_postgres_cache_block; 343 api->cache_block = &namecache_postgres_cache_block;
339 api->lookup_block = &namecache_postgres_lookup_block; 344 api->lookup_block = &namecache_postgres_lookup_block;
340 LOG(GNUNET_ERROR_TYPE_INFO, 345 LOG (GNUNET_ERROR_TYPE_INFO,
341 "Postgres namecache plugin running\n"); 346 "Postgres namecache plugin running\n");
342 return api; 347 return api;
343} 348}
344 349
@@ -350,16 +355,16 @@ libgnunet_plugin_namecache_postgres_init(void *cls)
350 * @return always NULL 355 * @return always NULL
351 */ 356 */
352void * 357void *
353libgnunet_plugin_namecache_postgres_done(void *cls) 358libgnunet_plugin_namecache_postgres_done (void *cls)
354{ 359{
355 struct GNUNET_NAMECACHE_PluginFunctions *api = cls; 360 struct GNUNET_NAMECACHE_PluginFunctions *api = cls;
356 struct Plugin *plugin = api->cls; 361 struct Plugin *plugin = api->cls;
357 362
358 database_shutdown(plugin); 363 database_shutdown (plugin);
359 plugin->cfg = NULL; 364 plugin->cfg = NULL;
360 GNUNET_free(api); 365 GNUNET_free (api);
361 LOG(GNUNET_ERROR_TYPE_DEBUG, 366 LOG (GNUNET_ERROR_TYPE_DEBUG,
362 "Postgres namecache plugin is finished\n"); 367 "Postgres namecache plugin is finished\n");
363 return NULL; 368 return NULL;
364} 369}
365 370