729b916ca4ef962ff9a54f752146a82153c9759b
[oweals/gnunet.git] / src / namestore / plugin_namestore_sqlite.c
1  /*
2   * This file is part of GNUnet
3   * (C) 2009-2013 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 3, 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 namestore/plugin_namestore_sqlite.c
23  * @brief sqlite-based namestore backend
24  * @author Christian Grothoff
25  */
26
27 #include "platform.h"
28 #include "gnunet_namestore_plugin.h"
29 #include "gnunet_namestore_service.h"
30 #include "namestore.h"
31 #include <sqlite3.h>
32
33 /**
34  * After how many ms "busy" should a DB operation fail for good?  A
35  * low value makes sure that we are more responsive to requests
36  * (especially PUTs).  A high value guarantees a higher success rate
37  * (SELECTs in iterate can take several seconds despite LIMIT=1).
38  *
39  * The default value of 1s should ensure that users do not experience
40  * huge latencies while at the same time allowing operations to
41  * succeed with reasonable probability.
42  */
43 #define BUSY_TIMEOUT_MS 1000
44
45
46 /**
47  * Log an error message at log-level 'level' that indicates
48  * a failure of the command 'cmd' on file 'filename'
49  * with the message given by strerror(errno).
50  */
51 #define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from (level, "namestore-sqlite", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); } while(0)
52
53 #define LOG(kind,...) GNUNET_log_from (kind, "namestore-sqlite", __VA_ARGS__)
54
55
56 /**
57  * Context for all functions in this plugin.
58  */
59 struct Plugin
60 {
61
62   const struct GNUNET_CONFIGURATION_Handle *cfg;
63
64   /**
65    * Database filename.
66    */
67   char *fn;
68
69   /**
70    * Native SQLite database handle.
71    */
72   sqlite3 *dbh;
73
74   /**
75    * Precompiled SQL for caching a block
76    */
77   sqlite3_stmt *cache_block;
78
79   /**
80    * Precompiled SQL for deleting an older block
81    */
82   sqlite3_stmt *delete_block;
83
84   /**
85    * Precompiled SQL for looking up a block
86    */
87   sqlite3_stmt *lookup_block;
88
89   /**
90    * Precompiled SQL for removing expired blocks
91    */
92   sqlite3_stmt *expire_blocks;
93
94   /**
95    * Precompiled SQL to store records.
96    */
97   sqlite3_stmt *store_records;
98
99   /**
100    * Precompiled SQL to deltete existing records.
101    */
102   sqlite3_stmt *delete_records;
103
104   /**
105    * Precompiled SQL for iterate records within a zone.
106    */
107   sqlite3_stmt *iterate_zone;
108
109   /**
110    * Precompiled SQL for iterate all records within all zones.
111    */
112   sqlite3_stmt *iterate_all_zones;
113
114   /**
115    * Precompiled SQL to for reverse lookup based on PKEY.
116    */
117   sqlite3_stmt *zone_to_name;
118
119 };
120
121
122 /**
123  * @brief Prepare a SQL statement
124  *
125  * @param dbh handle to the database
126  * @param zSql SQL statement, UTF-8 encoded
127  * @param ppStmt set to the prepared statement
128  * @return 0 on success
129  */
130 static int
131 sq_prepare (sqlite3 * dbh, const char *zSql, sqlite3_stmt ** ppStmt)
132 {
133   char *dummy;
134   int result;
135
136   result =
137       sqlite3_prepare_v2 (dbh, zSql, strlen (zSql), ppStmt,
138                           (const char **) &dummy);
139   LOG (GNUNET_ERROR_TYPE_DEBUG,
140        "Prepared `%s' / %p: %d\n", zSql, *ppStmt, result);
141   return result;
142 }
143
144
145 /**
146  * Create our database indices.
147  *
148  * @param dbh handle to the database
149  */
150 static void
151 create_indices (sqlite3 * dbh)
152 {
153   /* create indices */
154   if ( (SQLITE_OK !=
155         sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_query_hash ON ns096blocks (query,expiration_time)",
156                       NULL, NULL, NULL)) ||
157        (SQLITE_OK !=
158         sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_block_expiration ON ns096blocks (expiration_time)",
159                       NULL, NULL, NULL)) ||
160        (SQLITE_OK !=
161         sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_pkey_reverse ON ns097records (zone_private_key,pkey)",
162                       NULL, NULL, NULL)) ||
163        (SQLITE_OK !=
164         sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_pkey_iter ON ns097records (zone_private_key,rvalue)",
165                       NULL, NULL, NULL)) ||
166        (SQLITE_OK !=
167         sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS it_iter ON ns097records (rvalue)",
168                       NULL, NULL, NULL)) )
169     LOG (GNUNET_ERROR_TYPE_ERROR,
170          "Failed to create indices: %s\n", sqlite3_errmsg (dbh));
171 }
172
173
174 #if 0
175 #define CHECK(a) GNUNET_break(a)
176 #define ENULL NULL
177 #else
178 #define ENULL &e
179 #define ENULL_DEFINED 1
180 #define CHECK(a) if (! a) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "%s\n", e); sqlite3_free(e); }
181 #endif
182
183
184 /**
185  * Initialize the database connections and associated
186  * data structures (create tables and indices
187  * as needed as well).
188  *
189  * @param plugin the plugin context (state for this module)
190  * @return #GNUNET_OK on success
191  */
192 static int
193 database_setup (struct Plugin *plugin)
194 {
195   sqlite3_stmt *stmt;
196   char *afsdir;
197 #if ENULL_DEFINED
198   char *e;
199 #endif
200
201   if (GNUNET_OK !=
202       GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "namestore-sqlite",
203                                                "FILENAME", &afsdir))
204   {
205     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
206                                "namestore-sqlite", "FILENAME");
207     return GNUNET_SYSERR;
208   }
209   if (GNUNET_OK != GNUNET_DISK_file_test (afsdir))
210   {
211     if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir))
212     {
213       GNUNET_break (0);
214       GNUNET_free (afsdir);
215       return GNUNET_SYSERR;
216     }
217   }
218   /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */
219   plugin->fn = afsdir;
220
221   /* Open database and precompile statements */
222   if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK)
223   {
224     LOG (GNUNET_ERROR_TYPE_ERROR,
225          _("Unable to initialize SQLite: %s.\n"),
226          sqlite3_errmsg (plugin->dbh));
227     return GNUNET_SYSERR;
228   }
229   CHECK (SQLITE_OK ==
230          sqlite3_exec (plugin->dbh, "PRAGMA temp_store=MEMORY", NULL, NULL,
231                        ENULL));
232   CHECK (SQLITE_OK ==
233          sqlite3_exec (plugin->dbh, "PRAGMA synchronous=NORMAL", NULL, NULL,
234                        ENULL));
235   CHECK (SQLITE_OK ==
236          sqlite3_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF", NULL, NULL,
237                        ENULL));
238   CHECK (SQLITE_OK ==
239          sqlite3_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL", NULL,
240                        NULL, ENULL));
241   CHECK (SQLITE_OK ==
242          sqlite3_exec (plugin->dbh, "PRAGMA encoding=\"UTF-8\"", NULL,
243                        NULL, ENULL));
244   CHECK (SQLITE_OK ==
245          sqlite3_exec (plugin->dbh, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL,
246                        ENULL));
247   CHECK (SQLITE_OK ==
248          sqlite3_exec (plugin->dbh, "PRAGMA count_changes=OFF", NULL, NULL,
249                        ENULL));
250   CHECK (SQLITE_OK ==
251          sqlite3_exec (plugin->dbh, "PRAGMA page_size=4092", NULL, NULL,
252                        ENULL));
253
254   CHECK (SQLITE_OK == sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS));
255
256
257   /* Create tables */
258   CHECK (SQLITE_OK ==
259          sq_prepare (plugin->dbh,
260                      "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns096blocks'",
261                      &stmt));
262   if ((sqlite3_step (stmt) == SQLITE_DONE) &&
263       (sqlite3_exec
264        (plugin->dbh,
265         "CREATE TABLE ns096blocks ("
266         " query BLOB NOT NULL DEFAULT '',"
267         " block BLOB NOT NULL DEFAULT '',"
268         " expiration_time INT8 NOT NULL DEFAULT 0"
269         ")",
270         NULL, NULL, NULL) != SQLITE_OK))
271   {
272     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec");
273     sqlite3_finalize (stmt);
274     return GNUNET_SYSERR;
275   }
276   sqlite3_finalize (stmt);
277
278   CHECK (SQLITE_OK ==
279          sq_prepare (plugin->dbh,
280                      "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns097records'",
281                      &stmt));
282   if ((sqlite3_step (stmt) == SQLITE_DONE) &&
283       (sqlite3_exec
284        (plugin->dbh,
285         "CREATE TABLE ns097records ("
286         " zone_private_key BLOB NOT NULL DEFAULT '',"
287         " pkey BLOB,"
288         " rvalue INT8 NOT NULL DEFAULT '',"
289         " record_count INT NOT NULL DEFAULT 0,"
290         " record_data BLOB NOT NULL DEFAULT '',"
291         " label TEXT NOT NULL DEFAULT ''"
292         ")",
293         NULL, NULL, NULL) != SQLITE_OK))
294   {
295     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec");
296     sqlite3_finalize (stmt);
297     return GNUNET_SYSERR;
298   }
299   sqlite3_finalize (stmt);
300
301   create_indices (plugin->dbh);
302
303   if ((sq_prepare
304        (plugin->dbh,
305         "INSERT INTO ns096blocks (query,block,expiration_time) VALUES (?, ?, ?)",
306         &plugin->cache_block) != SQLITE_OK) ||
307       (sq_prepare
308        (plugin->dbh,
309         "DELETE FROM ns096blocks WHERE expiration_time<?",
310         &plugin->expire_blocks) != SQLITE_OK) ||
311       (sq_prepare
312        (plugin->dbh,
313         "DELETE FROM ns096blocks WHERE query=? AND expiration_time<=?",
314         &plugin->delete_block) != SQLITE_OK) ||
315       (sq_prepare
316        (plugin->dbh,
317         "SELECT block FROM ns096blocks WHERE query=? ORDER BY expiration_time DESC LIMIT 1",
318         &plugin->lookup_block) != SQLITE_OK) ||
319       (sq_prepare
320        (plugin->dbh,
321         "INSERT INTO ns097records (zone_private_key, pkey, rvalue, record_count, record_data, label)"
322         " VALUES (?, ?, ?, ?, ?, ?)",
323         &plugin->store_records) != SQLITE_OK) ||
324       (sq_prepare
325        (plugin->dbh,
326         "DELETE FROM ns097records WHERE zone_private_key=? AND label=?",
327         &plugin->delete_records) != SQLITE_OK) ||
328       (sq_prepare
329        (plugin->dbh,
330         "SELECT record_count,record_data,label"
331         " FROM ns097records WHERE zone_private_key=? AND pkey=?",
332         &plugin->zone_to_name) != SQLITE_OK) ||
333       (sq_prepare
334        (plugin->dbh,
335         "SELECT record_count,record_data,label"
336         " FROM ns097records WHERE zone_private_key=? ORDER BY rvalue LIMIT 1 OFFSET ?",
337         &plugin->iterate_zone) != SQLITE_OK) ||
338       (sq_prepare
339        (plugin->dbh,
340         "SELECT record_count,record_data,label,zone_private_key"
341         " FROM ns097records ORDER BY rvalue LIMIT 1 OFFSET ?",
342         &plugin->iterate_all_zones) != SQLITE_OK)
343       )
344   {
345     LOG_SQLITE (plugin,GNUNET_ERROR_TYPE_ERROR, "precompiling");
346     return GNUNET_SYSERR;
347   }
348   return GNUNET_OK;
349 }
350
351
352 /**
353  * Shutdown database connection and associate data
354  * structures.
355  * @param plugin the plugin context (state for this module)
356  */
357 static void
358 database_shutdown (struct Plugin *plugin)
359 {
360   int result;
361   sqlite3_stmt *stmt;
362
363   if (NULL != plugin->cache_block)
364     sqlite3_finalize (plugin->cache_block);
365   if (NULL != plugin->lookup_block)
366     sqlite3_finalize (plugin->lookup_block);
367   if (NULL != plugin->expire_blocks)
368     sqlite3_finalize (plugin->expire_blocks);
369   if (NULL != plugin->delete_block)
370     sqlite3_finalize (plugin->delete_block);
371   if (NULL != plugin->store_records)
372     sqlite3_finalize (plugin->store_records);
373   if (NULL != plugin->delete_records)
374     sqlite3_finalize (plugin->delete_records);
375   if (NULL != plugin->iterate_zone)
376     sqlite3_finalize (plugin->iterate_zone);
377   if (NULL != plugin->iterate_all_zones)
378     sqlite3_finalize (plugin->iterate_all_zones);
379   if (NULL != plugin->zone_to_name)
380     sqlite3_finalize (plugin->zone_to_name);
381   result = sqlite3_close (plugin->dbh);
382   if (result == SQLITE_BUSY)
383   {
384     LOG (GNUNET_ERROR_TYPE_WARNING,
385          _("Tried to close sqlite without finalizing all prepared statements.\n"));
386     stmt = sqlite3_next_stmt (plugin->dbh, NULL);
387     while (stmt != NULL)
388     {
389       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
390                        "Closing statement %p\n", stmt);
391       result = sqlite3_finalize (stmt);
392       if (result != SQLITE_OK)
393         GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite",
394                          "Failed to close statement %p: %d\n", stmt, result);
395       stmt = sqlite3_next_stmt (plugin->dbh, NULL);
396     }
397     result = sqlite3_close (plugin->dbh);
398   }
399   if (SQLITE_OK != result)
400     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close");
401
402   GNUNET_free_non_null (plugin->fn);
403 }
404
405
406 /**
407  * Removes any expired block.
408  *
409  * @param plugin the plugin
410  */
411 static void
412 namestore_sqlite_expire_blocks (struct Plugin *plugin)
413 {
414   struct GNUNET_TIME_Absolute now;
415   int n;
416
417   now = GNUNET_TIME_absolute_get ();
418   if (SQLITE_OK != sqlite3_bind_int64 (plugin->expire_blocks,
419                                        1, now.abs_value_us))
420   {
421     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
422                 "sqlite3_bind_XXXX");
423     if (SQLITE_OK != sqlite3_reset (plugin->expire_blocks))
424       LOG_SQLITE (plugin,
425                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
426                   "sqlite3_reset");
427     return;
428   }
429   n = sqlite3_step (plugin->expire_blocks);
430   if (SQLITE_OK != sqlite3_reset (plugin->expire_blocks))
431     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
432                 "sqlite3_reset");
433   switch (n)
434   {
435   case SQLITE_DONE:
436     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Records expired\n");
437     return;
438   case SQLITE_BUSY:
439     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
440                 "sqlite3_step");
441     return;
442   default:
443     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
444                 "sqlite3_step");
445     return;
446   }
447 }
448
449
450 /**
451  * Cache a block in the datastore.
452  *
453  * @param cls closure (internal context for the plugin)
454  * @param block block to cache
455  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
456  */
457 static int
458 namestore_sqlite_cache_block (void *cls,
459                               const struct GNUNET_NAMESTORE_Block *block)
460 {
461   struct Plugin *plugin = cls;
462   struct GNUNET_HashCode query;
463   struct GNUNET_TIME_Absolute expiration;
464   int64_t dval;
465   size_t block_size;
466   int n;
467
468   namestore_sqlite_expire_blocks (plugin);
469   GNUNET_CRYPTO_hash (&block->derived_key,
470                       sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
471                       &query);
472   expiration = GNUNET_TIME_absolute_ntoh (block->expiration_time);
473   dval = (int64_t) expiration.abs_value_us;
474   if (dval < 0)
475     dval = INT64_MAX;
476   block_size = ntohl (block->purpose.size) +
477     sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) +
478     sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
479   if (block_size > 64 * 65536)
480   {
481     GNUNET_break (0);
482     return GNUNET_SYSERR;
483   }
484
485   /* delete old version of the block */
486   if ( (SQLITE_OK !=
487         sqlite3_bind_blob (plugin->delete_block, 1,
488                            &query, sizeof (struct GNUNET_HashCode),
489                            SQLITE_STATIC)) ||
490        (SQLITE_OK !=
491         sqlite3_bind_int64 (plugin->delete_block,
492                             2, dval)) )
493   {
494     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
495                 "sqlite3_bind_XXXX");
496     if (SQLITE_OK != sqlite3_reset (plugin->delete_block))
497       LOG_SQLITE (plugin,
498                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
499                   "sqlite3_reset");
500     return GNUNET_SYSERR;
501   }
502   n = sqlite3_step (plugin->delete_block);
503   switch (n)
504   {
505   case SQLITE_DONE:
506     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Old block deleted\n");
507     break;
508   case SQLITE_BUSY:
509     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
510                 "sqlite3_step");
511     break;
512   default:
513     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
514                 "sqlite3_step");
515     break;
516   }
517   if (SQLITE_OK != sqlite3_reset (plugin->delete_block))
518     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
519                 "sqlite3_reset");
520
521   /* insert new version of the block */
522   if ((SQLITE_OK !=
523        sqlite3_bind_blob (plugin->cache_block, 1,
524                           &query, sizeof (struct GNUNET_HashCode),
525                           SQLITE_STATIC)) ||
526       (SQLITE_OK !=
527        sqlite3_bind_blob (plugin->cache_block, 2,
528                           block, block_size,
529                           SQLITE_STATIC)) ||
530       (SQLITE_OK !=
531        sqlite3_bind_int64 (plugin->cache_block, 3,
532                            dval)))
533   {
534     LOG_SQLITE (plugin,
535                 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
536                 "sqlite3_bind_XXXX");
537     if (SQLITE_OK != sqlite3_reset (plugin->cache_block))
538       LOG_SQLITE (plugin,
539                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
540                   "sqlite3_reset");
541     return GNUNET_SYSERR;
542
543   }
544   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
545               "Caching block under derived key `%s'\n",
546               GNUNET_h2s_full (&query));
547   n = sqlite3_step (plugin->cache_block);
548   if (SQLITE_OK != sqlite3_reset (plugin->cache_block))
549     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
550                 "sqlite3_reset");
551   switch (n)
552   {
553   case SQLITE_DONE:
554     LOG (GNUNET_ERROR_TYPE_DEBUG,
555          "Record stored\n");
556     return GNUNET_OK;
557   case SQLITE_BUSY:
558     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
559                 "sqlite3_step");
560     return GNUNET_NO;
561   default:
562     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
563                 "sqlite3_step");
564     return GNUNET_SYSERR;
565   }
566 }
567
568
569 /**
570  * Get the block for a particular zone and label in the
571  * datastore.  Will return at most one result to the iterator.
572  *
573  * @param cls closure (internal context for the plugin)
574  * @param query hash of public key derived from the zone and the label
575  * @param iter function to call with the result
576  * @param iter_cls closure for @a iter
577  * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
578  */
579 static int
580 namestore_sqlite_lookup_block (void *cls,
581                                const struct GNUNET_HashCode *query,
582                                GNUNET_NAMESTORE_BlockCallback iter, void *iter_cls)
583 {
584   struct Plugin *plugin = cls;
585   int ret;
586   int sret;
587   size_t block_size;
588   const struct GNUNET_NAMESTORE_Block *block;
589
590   if (SQLITE_OK != sqlite3_bind_blob (plugin->lookup_block, 1,
591                                       query, sizeof (struct GNUNET_HashCode),
592                                       SQLITE_STATIC))
593   {
594     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
595                 "sqlite3_bind_XXXX");
596     if (SQLITE_OK != sqlite3_reset (plugin->lookup_block))
597       LOG_SQLITE (plugin,
598                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
599                   "sqlite3_reset");
600     return GNUNET_SYSERR;
601   }
602   ret = GNUNET_NO;
603   if (SQLITE_ROW == (sret = sqlite3_step (plugin->lookup_block)))
604   {
605     block = sqlite3_column_blob (plugin->lookup_block, 0);
606     block_size = sqlite3_column_bytes (plugin->lookup_block, 0);
607     if ( (block_size < sizeof (struct GNUNET_NAMESTORE_Block)) ||
608          (ntohl (block->purpose.size) +
609           sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) +
610           sizeof (struct GNUNET_CRYPTO_EcdsaSignature) != block_size) )
611     {
612       GNUNET_break (0);
613       ret = GNUNET_SYSERR;
614     }
615     else
616     {
617       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
618                   "Found block under derived key `%s'\n",
619                   GNUNET_h2s_full (query));
620       iter (iter_cls, block);
621       ret = GNUNET_YES;
622     }
623   }
624   else
625   {
626     if (SQLITE_DONE != sret)
627     {
628       LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
629       ret = GNUNET_SYSERR;
630     }
631     else
632     {
633       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
634                   "No block found under derived key `%s'\n",
635                   GNUNET_h2s_full (query));
636     }
637   }
638   if (SQLITE_OK != sqlite3_reset (plugin->lookup_block))
639     LOG_SQLITE (plugin,
640                 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
641                 "sqlite3_reset");
642   return ret;
643 }
644
645
646 /**
647  * Store a record in the datastore.  Removes any existing record in the
648  * same zone with the same name.
649  *
650  * @param cls closure (internal context for the plugin)
651  * @param zone_key private key of the zone
652  * @param label name that is being mapped (at most 255 characters long)
653  * @param rd_count number of entries in @a rd array
654  * @param rd array of records with data to store
655  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
656  */
657 static int
658 namestore_sqlite_store_records (void *cls,
659                                 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
660                                 const char *label,
661                                 unsigned int rd_count,
662                                 const struct GNUNET_NAMESTORE_RecordData *rd)
663 {
664   struct Plugin *plugin = cls;
665   int n;
666   struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
667   uint64_t rvalue;
668   size_t data_size;
669   unsigned int i;
670
671   memset (&pkey, 0, sizeof (pkey));
672   for (i=0;i<rd_count;i++)
673     if (GNUNET_NAMESTORE_TYPE_PKEY == rd[i].record_type)
674     {
675       GNUNET_break (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) == rd[i].data_size);
676       memcpy (&pkey,
677               rd[i].data,
678               rd[i].data_size);
679       break;
680     }
681   rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
682   data_size = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
683   if (data_size > 64 * 65536)
684   {
685     GNUNET_break (0);
686     return GNUNET_SYSERR;
687   }
688   {
689     char data[data_size];
690
691     if (data_size != GNUNET_NAMESTORE_records_serialize (rd_count, rd,
692                                                          data_size, data))
693     {
694       GNUNET_break (0);
695       return GNUNET_SYSERR;
696     }
697
698     /* First delete 'old' records */
699     if ((SQLITE_OK != sqlite3_bind_blob (plugin->delete_records, 1,
700                                          zone_key, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), SQLITE_STATIC)) ||
701         (SQLITE_OK != sqlite3_bind_text (plugin->delete_records, 2, label, -1, SQLITE_STATIC)))
702     {
703       LOG_SQLITE (plugin,
704                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
705                   "sqlite3_bind_XXXX");
706       if (SQLITE_OK != sqlite3_reset (plugin->delete_records))
707         LOG_SQLITE (plugin,
708                     GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
709                     "sqlite3_reset");
710       return GNUNET_SYSERR;
711
712     }
713     n = sqlite3_step (plugin->delete_records);
714     if (SQLITE_OK != sqlite3_reset (plugin->delete_records))
715       LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
716                   "sqlite3_reset");
717
718     if (0 != rd_count)
719     {
720       if ((SQLITE_OK != sqlite3_bind_blob (plugin->store_records, 1,
721                                            zone_key, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), SQLITE_STATIC)) ||
722           (SQLITE_OK != sqlite3_bind_blob (plugin->store_records, 2,
723                                            &pkey, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), SQLITE_STATIC)) ||
724           (SQLITE_OK != sqlite3_bind_int64 (plugin->store_records, 3, rvalue)) ||
725           (SQLITE_OK != sqlite3_bind_int (plugin->store_records, 4, rd_count)) ||
726           (SQLITE_OK != sqlite3_bind_blob (plugin->store_records, 5, data, data_size, SQLITE_STATIC)) ||
727           (SQLITE_OK != sqlite3_bind_text (plugin->store_records, 6, label, -1, SQLITE_STATIC)))
728       {
729         LOG_SQLITE (plugin,
730                     GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
731                     "sqlite3_bind_XXXX");
732         if (SQLITE_OK != sqlite3_reset (plugin->store_records))
733           LOG_SQLITE (plugin,
734                       GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
735                       "sqlite3_reset");
736         return GNUNET_SYSERR;
737       }
738       n = sqlite3_step (plugin->store_records);
739       if (SQLITE_OK != sqlite3_reset (plugin->store_records))
740         LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
741                     "sqlite3_reset");
742     }
743   }
744   switch (n)
745   {
746   case SQLITE_DONE:
747     if (0 != rd_count)
748       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Record stored\n");
749     else
750       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Record deleted\n");
751     return GNUNET_OK;
752   case SQLITE_BUSY:
753     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
754                 "sqlite3_step");
755     return GNUNET_NO;
756   default:
757     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
758                 "sqlite3_step");
759     return GNUNET_SYSERR;
760   }
761 }
762
763
764 /**
765  * The given 'sqlite' statement has been prepared to be run.
766  * It will return a record which should be given to the iterator.
767  * Runs the statement and parses the returned record.
768  *
769  * @param plugin plugin context
770  * @param stmt to run (and then clean up)
771  * @param zone_key private key of the zone
772  * @param iter iterator to call with the result
773  * @param iter_cls closure for @a iter
774  * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
775  */
776 static int
777 get_record_and_call_iterator (struct Plugin *plugin,
778                               sqlite3_stmt *stmt,
779                               const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
780                               GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
781 {
782   unsigned int record_count;
783   size_t data_size;
784   const char *data;
785   const char *label;
786   int ret;
787   int sret;
788
789   ret = GNUNET_NO;
790   if (SQLITE_ROW == (sret = sqlite3_step (stmt)))
791   {
792     record_count = sqlite3_column_int (stmt, 0);
793     data_size = sqlite3_column_bytes (stmt, 1);
794     data = sqlite3_column_blob (stmt, 1);
795     label = (const char*) sqlite3_column_text (stmt, 2);
796     if (NULL == zone_key)
797     {
798       /* must be "iterate_all_zones", got one extra return value */
799       if (sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey) !=
800           sqlite3_column_bytes (stmt, 3))
801       {
802         GNUNET_break (0);
803         ret = GNUNET_SYSERR;
804       }
805       else
806       {
807         zone_key = sqlite3_column_blob (stmt, 3);
808       }
809     }
810     if (record_count > 64 * 1024)
811     {
812       /* sanity check, don't stack allocate far too much just
813          because database might contain a large value here */
814       GNUNET_break (0);
815       ret = GNUNET_SYSERR;
816     }
817     else
818     {
819       struct GNUNET_NAMESTORE_RecordData rd[record_count];
820
821       if (GNUNET_OK !=
822           GNUNET_NAMESTORE_records_deserialize (data_size, data,
823                                                 record_count, rd))
824       {
825         GNUNET_break (0);
826         ret = GNUNET_SYSERR;
827       }
828       else if (NULL != zone_key)
829       {
830         if (NULL != iter)
831                 iter (iter_cls, zone_key, label, record_count, rd);
832         ret = GNUNET_YES;
833       }
834     }
835   }
836   else
837   {
838     if (SQLITE_DONE != sret)
839       LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
840   }
841   if (SQLITE_OK != sqlite3_reset (stmt))
842     LOG_SQLITE (plugin,
843                 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
844                 "sqlite3_reset");
845   return ret;
846 }
847
848
849 /**
850  * Iterate over the results for a particular key and zone in the
851  * datastore.  Will return at most one result to the iterator.
852  *
853  * @param cls closure (internal context for the plugin)
854  * @param zone hash of public key of the zone, NULL to iterate over all zones
855  * @param offset offset in the list of all matching records
856  * @param iter function to call with the result
857  * @param iter_cls closure for @a iter
858  * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
859  */
860 static int
861 namestore_sqlite_iterate_records (void *cls,
862                                   const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
863                                   uint64_t offset,
864                                   GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
865 {
866   struct Plugin *plugin = cls;
867   sqlite3_stmt *stmt;
868   int err;
869
870   if (NULL == zone)
871   {
872     stmt = plugin->iterate_all_zones;
873     err = (SQLITE_OK != sqlite3_bind_int64 (stmt, 1,
874                                             offset));
875   }
876   else
877   {
878     stmt = plugin->iterate_zone;
879     err = ( (SQLITE_OK != sqlite3_bind_blob (stmt, 1,
880                                              zone, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
881                                              SQLITE_STATIC)) ||
882             (SQLITE_OK != sqlite3_bind_int64 (stmt, 2,
883                                               offset)) );
884   }
885   if (err)
886   {
887     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
888                 "sqlite3_bind_XXXX");
889     if (SQLITE_OK != sqlite3_reset (stmt))
890       LOG_SQLITE (plugin,
891                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
892                   "sqlite3_reset");
893     return GNUNET_SYSERR;
894   }
895   return get_record_and_call_iterator (plugin, stmt, zone, iter, iter_cls);
896 }
897
898
899 /**
900  * Look for an existing PKEY delegation record for a given public key.
901  * Returns at most one result to the iterator.
902  *
903  * @param cls closure (internal context for the plugin)
904  * @param zone private key of the zone to look up in, never NULL
905  * @param value_zone public key of the target zone (value), never NULL
906  * @param iter function to call with the result
907  * @param iter_cls closure for @a iter
908  * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
909  */
910 static int
911 namestore_sqlite_zone_to_name (void *cls,
912                                const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
913                                const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone,
914                                GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
915 {
916   struct Plugin *plugin = cls;
917   sqlite3_stmt *stmt;
918
919   stmt = plugin->zone_to_name;
920   if ( (SQLITE_OK != sqlite3_bind_blob (stmt, 1,
921                                         zone, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
922                                         SQLITE_STATIC)) ||
923        (SQLITE_OK != sqlite3_bind_blob (stmt, 2,
924                                         value_zone, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
925                                         SQLITE_STATIC)) )
926   {
927     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
928                 "sqlite3_bind_XXXX");
929     if (SQLITE_OK != sqlite3_reset (stmt))
930       LOG_SQLITE (plugin,
931                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
932                   "sqlite3_reset");
933     return GNUNET_SYSERR;
934   }
935   LOG (GNUNET_ERROR_TYPE_DEBUG,
936        "Performing reverse lookup for `%s'\n",
937        GNUNET_NAMESTORE_z2s (value_zone));
938
939   return get_record_and_call_iterator (plugin, stmt, zone, iter, iter_cls);
940 }
941
942
943 /**
944  * Entry point for the plugin.
945  *
946  * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*"
947  * @return NULL on error, otherwise the plugin context
948  */
949 void *
950 libgnunet_plugin_namestore_sqlite_init (void *cls)
951 {
952   static struct Plugin plugin;
953   const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
954   struct GNUNET_NAMESTORE_PluginFunctions *api;
955
956   if (NULL != plugin.cfg)
957     return NULL;                /* can only initialize once! */
958   memset (&plugin, 0, sizeof (struct Plugin));
959   plugin.cfg = cfg;
960   if (GNUNET_OK != database_setup (&plugin))
961   {
962     database_shutdown (&plugin);
963     return NULL;
964   }
965   api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
966   api->cls = &plugin;
967   api->cache_block = &namestore_sqlite_cache_block;
968   api->lookup_block = &namestore_sqlite_lookup_block;
969   api->store_records = &namestore_sqlite_store_records;
970   api->iterate_records = &namestore_sqlite_iterate_records;
971   api->zone_to_name = &namestore_sqlite_zone_to_name;
972   LOG (GNUNET_ERROR_TYPE_INFO,
973        _("Sqlite database running\n"));
974   return api;
975 }
976
977
978 /**
979  * Exit point from the plugin.
980  *
981  * @param cls the plugin context (as returned by "init")
982  * @return always NULL
983  */
984 void *
985 libgnunet_plugin_namestore_sqlite_done (void *cls)
986 {
987   struct GNUNET_NAMESTORE_PluginFunctions *api = cls;
988   struct Plugin *plugin = api->cls;
989
990   database_shutdown (plugin);
991   plugin->cfg = NULL;
992   GNUNET_free (api);
993   LOG (GNUNET_ERROR_TYPE_DEBUG,
994        "sqlite plugin is finished\n");
995   return NULL;
996 }
997
998 /* end of plugin_namestore_sqlite.c */