GNUnet  0.10.x
plugin_namestore_sqlite.c
Go to the documentation of this file.
1 /*
2  * This file is part of GNUnet
3  * Copyright (C) 2009-2017 GNUnet e.V.
4  *
5  * GNUnet is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU Affero General Public License as published
7  * by the Free Software Foundation, either version 3 of the License,
8  * or (at your 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  * Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
27 #include "platform.h"
30 #include "gnunet_gnsrecord_lib.h"
31 #include "gnunet_sq_lib.h"
32 #include "namestore.h"
33 #include <sqlite3.h>
34 
45 #define BUSY_TIMEOUT_MS 1000
46 
47 
53 #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)
54 
55 #define LOG(kind, ...) GNUNET_log_from(kind, "namestore-sqlite", __VA_ARGS__)
56 
57 
61 struct Plugin {
62  const struct GNUNET_CONFIGURATION_Handle *cfg;
63 
67  char *fn;
68 
72  sqlite3 *dbh;
73 
77  sqlite3_stmt *store_records;
78 
82  sqlite3_stmt *delete_records;
83 
87  sqlite3_stmt *iterate_zone;
88 
92  sqlite3_stmt *iterate_all_zones;
93 
97  sqlite3_stmt *zone_to_name;
98 
102  sqlite3_stmt *lookup_label;
103 };
104 
105 
114 static int
116 {
117  char *sqlite_filename;
118  struct GNUNET_SQ_ExecuteStatement es[] = {
119  GNUNET_SQ_make_try_execute("PRAGMA temp_store=MEMORY"),
120  GNUNET_SQ_make_try_execute("PRAGMA synchronous=NORMAL"),
121  GNUNET_SQ_make_try_execute("PRAGMA legacy_file_format=OFF"),
122  GNUNET_SQ_make_try_execute("PRAGMA auto_vacuum=INCREMENTAL"),
123  GNUNET_SQ_make_try_execute("PRAGMA encoding=\"UTF-8\""),
124  GNUNET_SQ_make_try_execute("PRAGMA locking_mode=EXCLUSIVE"),
125  GNUNET_SQ_make_try_execute("PRAGMA journal_mode=WAL"),
126  GNUNET_SQ_make_try_execute("PRAGMA page_size=4092"),
127  GNUNET_SQ_make_execute("CREATE TABLE IF NOT EXISTS ns098records ("
128  " uid INTEGER PRIMARY KEY,"
129  " zone_private_key BLOB NOT NULL,"
130  " pkey BLOB,"
131  " rvalue INT8 NOT NULL,"
132  " record_count INT NOT NULL,"
133  " record_data BLOB NOT NULL,"
134  " label TEXT NOT NULL"
135  ")"),
136  GNUNET_SQ_make_try_execute("CREATE INDEX IF NOT EXISTS ir_pkey_reverse "
137  "ON ns098records (zone_private_key,pkey)"),
138  GNUNET_SQ_make_try_execute("CREATE INDEX IF NOT EXISTS ir_pkey_iter "
139  "ON ns098records (zone_private_key,uid)"),
141  };
142  struct GNUNET_SQ_PrepareStatement ps[] = {
143  GNUNET_SQ_make_prepare("INSERT INTO ns098records "
144  "(zone_private_key,pkey,rvalue,record_count,record_data,label)"
145  " VALUES (?, ?, ?, ?, ?, ?)",
146  &plugin->store_records),
147  GNUNET_SQ_make_prepare("DELETE FROM ns098records "
148  "WHERE zone_private_key=? AND label=?",
149  &plugin->delete_records),
150  GNUNET_SQ_make_prepare("SELECT uid,record_count,record_data,label"
151  " FROM ns098records"
152  " WHERE zone_private_key=? AND pkey=?",
153  &plugin->zone_to_name),
154  GNUNET_SQ_make_prepare("SELECT uid,record_count,record_data,label"
155  " FROM ns098records"
156  " WHERE zone_private_key=? AND uid > ?"
157  " ORDER BY uid ASC"
158  " LIMIT ?",
159  &plugin->iterate_zone),
160  GNUNET_SQ_make_prepare("SELECT uid,record_count,record_data,label,zone_private_key"
161  " FROM ns098records"
162  " WHERE uid > ?"
163  " ORDER BY uid ASC"
164  " LIMIT ?",
165  &plugin->iterate_all_zones),
166  GNUNET_SQ_make_prepare("SELECT uid,record_count,record_data,label"
167  " FROM ns098records"
168  " WHERE zone_private_key=? AND label=?",
169  &plugin->lookup_label),
171  };
172 
173  if (GNUNET_OK !=
175  "namestore-sqlite",
176  "FILENAME",
177  &sqlite_filename))
178  {
180  "namestore-sqlite",
181  "FILENAME");
182  return GNUNET_SYSERR;
183  }
184  if (GNUNET_OK !=
185  GNUNET_DISK_file_test(sqlite_filename))
186  {
187  if (GNUNET_OK !=
188  GNUNET_DISK_directory_create_for_file(sqlite_filename))
189  {
190  GNUNET_break(0);
191  GNUNET_free(sqlite_filename);
192  return GNUNET_SYSERR;
193  }
194  }
195  /* sqlite_filename should be UTF-8-encoded. If it isn't, it's a bug */
196  plugin->fn = sqlite_filename;
197 
198  /* Open database and precompile statements */
199  if (SQLITE_OK !=
200  sqlite3_open(plugin->fn,
201  &plugin->dbh))
202  {
204  _("Unable to initialize SQLite: %s.\n"),
205  sqlite3_errmsg(plugin->dbh));
206  return GNUNET_SYSERR;
207  }
208  GNUNET_break(SQLITE_OK ==
209  sqlite3_busy_timeout(plugin->dbh,
210  BUSY_TIMEOUT_MS));
211  if (GNUNET_OK !=
213  es))
214  {
215  GNUNET_break(0);
217  _("Failed to setup database at `%s'\n"),
218  plugin->fn);
219  return GNUNET_SYSERR;
220  }
221 
222  if (GNUNET_OK !=
223  GNUNET_SQ_prepare(plugin->dbh,
224  ps))
225  {
226  GNUNET_break(0);
228  _("Failed to setup database at `%s'\n"),
229  plugin->fn);
230  return GNUNET_SYSERR;
231  }
232  return GNUNET_OK;
233 }
234 
235 
241 static void
243 {
244  int result;
245  sqlite3_stmt *stmt;
246 
247  if (NULL != plugin->store_records)
248  sqlite3_finalize(plugin->store_records);
249  if (NULL != plugin->delete_records)
250  sqlite3_finalize(plugin->delete_records);
251  if (NULL != plugin->iterate_zone)
252  sqlite3_finalize(plugin->iterate_zone);
253  if (NULL != plugin->iterate_all_zones)
254  sqlite3_finalize(plugin->iterate_all_zones);
255  if (NULL != plugin->zone_to_name)
256  sqlite3_finalize(plugin->zone_to_name);
257  if (NULL != plugin->lookup_label)
258  sqlite3_finalize(plugin->lookup_label);
259  result = sqlite3_close(plugin->dbh);
260  if (result == SQLITE_BUSY)
261  {
263  _("Tried to close sqlite without finalizing all prepared statements.\n"));
264  stmt = sqlite3_next_stmt(plugin->dbh,
265  NULL);
266  while (NULL != stmt)
267  {
269  "sqlite",
270  "Closing statement %p\n",
271  stmt);
272  result = sqlite3_finalize(stmt);
273  if (result != SQLITE_OK)
275  "sqlite",
276  "Failed to close statement %p: %d\n",
277  stmt,
278  result);
279  stmt = sqlite3_next_stmt(plugin->dbh,
280  NULL);
281  }
282  result = sqlite3_close(plugin->dbh);
283  }
284  if (SQLITE_OK != result)
285  LOG_SQLITE(plugin,
287  "sqlite3_close");
288 
289  GNUNET_free_non_null(plugin->fn);
290 }
291 
292 
304 static int
306  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
307  const char *label,
308  unsigned int rd_count,
309  const struct GNUNET_GNSRECORD_Data *rd)
310 {
311  struct Plugin *plugin = cls;
312  int n;
313  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
314  uint64_t rvalue;
315  ssize_t data_size;
316 
317  memset(&pkey,
318  0,
319  sizeof(pkey));
320  for (unsigned int i = 0; i < rd_count; i++)
321  if (GNUNET_GNSRECORD_TYPE_PKEY == rd[i].record_type)
322  {
324  rd[i].data_size);
325  GNUNET_memcpy(&pkey,
326  rd[i].data,
327  rd[i].data_size);
328  break;
329  }
331  UINT64_MAX);
332  data_size = GNUNET_GNSRECORD_records_get_size(rd_count,
333  rd);
334  if (data_size < 0)
335  {
336  GNUNET_break(0);
337  return GNUNET_SYSERR;
338  }
339  if (data_size > 64 * 65536)
340  {
341  GNUNET_break(0);
342  return GNUNET_SYSERR;
343  }
344  {
345  /* First delete 'old' records */
346  char data[data_size];
347  struct GNUNET_SQ_QueryParam dparams[] = {
351  };
352  ssize_t ret;
353 
354  ret = GNUNET_GNSRECORD_records_serialize(rd_count,
355  rd,
356  data_size,
357  data);
358  if ((ret < 0) ||
359  (data_size != ret))
360  {
361  GNUNET_break(0);
362  return GNUNET_SYSERR;
363  }
364  if (GNUNET_OK !=
366  dparams))
367  {
368  LOG_SQLITE(plugin,
370  "sqlite3_bind_XXXX");
371  GNUNET_SQ_reset(plugin->dbh,
372  plugin->delete_records);
373  return GNUNET_SYSERR;
374  }
375  n = sqlite3_step(plugin->delete_records);
376  GNUNET_SQ_reset(plugin->dbh,
377  plugin->delete_records);
378 
379  if (0 != rd_count)
380  {
381  uint32_t rd_count32 = (uint32_t)rd_count;
382  struct GNUNET_SQ_QueryParam sparams[] = {
386  GNUNET_SQ_query_param_uint32(&rd_count32),
387  GNUNET_SQ_query_param_fixed_size(data, data_size),
390  };
391 
392  if (GNUNET_OK !=
394  sparams))
395  {
396  LOG_SQLITE(plugin,
398  "sqlite3_bind_XXXX");
399  GNUNET_SQ_reset(plugin->dbh,
400  plugin->store_records);
401  return GNUNET_SYSERR;
402  }
403  n = sqlite3_step(plugin->store_records);
404  GNUNET_SQ_reset(plugin->dbh,
405  plugin->store_records);
406  }
407  }
408  switch (n)
409  {
410  case SQLITE_DONE:
411  if (0 != rd_count)
413  "sqlite",
414  "Record stored\n");
415  else
417  "sqlite",
418  "Record deleted\n");
419  return GNUNET_OK;
420 
421  case SQLITE_BUSY:
422  LOG_SQLITE(plugin,
424  "sqlite3_step");
425  return GNUNET_NO;
426 
427  default:
428  LOG_SQLITE(plugin,
430  "sqlite3_step");
431  return GNUNET_SYSERR;
432  }
433 }
434 
435 
449 static int
451  sqlite3_stmt *stmt,
452  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
453  uint64_t limit,
455  void *iter_cls)
456 {
457  int ret;
458  int sret;
459 
460  ret = GNUNET_OK;
461  for (uint64_t i = 0; i < limit; i++)
462  {
463  sret = sqlite3_step(stmt);
464 
465  if (SQLITE_DONE == sret)
466  {
468  "Iteration done (no results)\n");
469  ret = GNUNET_NO;
470  break;
471  }
472  if (SQLITE_ROW != sret)
473  {
474  LOG_SQLITE(plugin,
476  "sqlite_step");
477  ret = GNUNET_SYSERR;
478  break;
479  }
480 
481  {
482  uint64_t seq;
483  uint32_t record_count;
484  size_t data_size;
485  void *data;
486  char *label;
488  struct GNUNET_SQ_ResultSpec rs[] = {
490  GNUNET_SQ_result_spec_uint32(&record_count),
492  &data_size),
495  };
496  struct GNUNET_SQ_ResultSpec rsx[] = {
498  GNUNET_SQ_result_spec_uint32(&record_count),
500  &data_size),
504  };
505 
506  ret = GNUNET_SQ_extract_result(stmt,
507  (NULL == zone_key)
508  ? rsx
509  : rs);
510  if ((GNUNET_OK != ret) ||
511  (record_count > 64 * 1024))
512  {
513  /* sanity check, don't stack allocate far too much just
514  because database might contain a large value here */
515  GNUNET_break(0);
516  ret = GNUNET_SYSERR;
517  break;
518  }
519  else
520  {
521  struct GNUNET_GNSRECORD_Data rd[record_count];
522 
523  GNUNET_assert(0 != seq);
524  if (GNUNET_OK !=
526  data,
527  record_count,
528  rd))
529  {
530  GNUNET_break(0);
531  ret = GNUNET_SYSERR;
532  break;
533  }
534  else
535  {
536  if (NULL != zone_key)
537  zk = *zone_key;
538  if (NULL != iter)
539  iter(iter_cls,
540  seq,
541  &zk,
542  label,
543  record_count,
544  rd);
545  }
546  }
548  }
549  }
550  GNUNET_SQ_reset(plugin->dbh,
551  stmt);
552  return ret;
553 }
554 
555 
566 static int
568  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
569  const char *label,
571  void *iter_cls)
572 {
573  struct Plugin *plugin = cls;
574  struct GNUNET_SQ_QueryParam params[] = {
578  };
579 
580  if (NULL == zone)
581  {
582  GNUNET_break(0);
583  return GNUNET_SYSERR;
584  }
585  if (GNUNET_OK !=
587  params))
588  {
590  "sqlite3_bind_XXXX");
591  GNUNET_SQ_reset(plugin->dbh,
592  plugin->lookup_label);
593  return GNUNET_SYSERR;
594  }
595  return get_records_and_call_iterator(plugin,
596  plugin->lookup_label,
597  zone,
598  1,
599  iter,
600  iter_cls);
601 }
602 
603 
616 static int
618  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
619  uint64_t serial,
620  uint64_t limit,
622  void *iter_cls)
623 {
624  struct Plugin *plugin = cls;
625  sqlite3_stmt *stmt;
626  int err;
627 
628  if (NULL == zone)
629  {
630  struct GNUNET_SQ_QueryParam params[] = {
634  };
635 
636  stmt = plugin->iterate_all_zones;
637  err = GNUNET_SQ_bind(stmt,
638  params);
639  }
640  else
641  {
642  struct GNUNET_SQ_QueryParam params[] = {
647  };
648 
649  stmt = plugin->iterate_zone;
650  err = GNUNET_SQ_bind(stmt,
651  params);
652  }
653  if (GNUNET_OK != err)
654  {
655  LOG_SQLITE(plugin,
657  "sqlite3_bind_XXXX");
658  GNUNET_SQ_reset(plugin->dbh,
659  stmt);
660  return GNUNET_SYSERR;
661  }
662  return get_records_and_call_iterator(plugin,
663  stmt,
664  zone,
665  limit,
666  iter,
667  iter_cls);
668 }
669 
670 
682 static int
684  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
685  const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone,
687  void *iter_cls)
688 {
689  struct Plugin *plugin = cls;
690  struct GNUNET_SQ_QueryParam params[] = {
694  };
695 
696  if (GNUNET_OK !=
698  params))
699  {
700  LOG_SQLITE(plugin,
702  "sqlite3_bind_XXXX");
703  GNUNET_SQ_reset(plugin->dbh,
704  plugin->zone_to_name);
705  return GNUNET_SYSERR;
706  }
708  "Performing reverse lookup for `%s'\n",
709  GNUNET_GNSRECORD_z2s(value_zone));
710  return get_records_and_call_iterator(plugin,
711  plugin->zone_to_name,
712  zone,
713  1,
714  iter,
715  iter_cls);
716 }
717 
718 
725 void *
727 {
728  static struct Plugin plugin;
729  const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
731 
732  if (NULL != plugin.cfg)
733  return NULL; /* can only initialize once! */
734  memset(&plugin,
735  0,
736  sizeof(struct Plugin));
737  plugin.cfg = cfg;
738  if (GNUNET_OK != database_setup(&plugin))
739  {
740  database_shutdown(&plugin);
741  return NULL;
742  }
744  api->cls = &plugin;
750  _("Sqlite database running\n"));
751  return api;
752 }
753 
754 
761 void *
763 {
765  struct Plugin *plugin = api->cls;
766 
767  database_shutdown(plugin);
768  plugin->cfg = NULL;
769  GNUNET_free(api);
771  "sqlite plugin is finished\n");
772  return NULL;
773 }
774 
775 /* end of plugin_namestore_sqlite.c */
int GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory)...
Definition: disk.c:541
GNUNET_NETWORK_STRUCT_END ssize_t GNUNET_GNSRECORD_records_get_size(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Calculate how many bytes we will need to serialize the given records.
static int get_records_and_call_iterator(struct Plugin *plugin, sqlite3_stmt *stmt, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
The given &#39;sqlite&#39; statement has been prepared to be run.
sqlite3_stmt * iterate_all_zones
Precompiled SQL for iterate all records within all zones.
Description of a DB result cell.
#define GNUNET_SQ_EXECUTE_STATEMENT_END
Terminator for executable statement list.
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_uint32(uint32_t *u32)
uint32_t expected.
static int namestore_sqlite_iterate_records(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, uint64_t serial, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Iterate over the results for a particular key and zone in the datastore.
Information needed to run a list of SQL statements using GNUNET_SQ_exec_statements().
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
ssize_t GNUNET_GNSRECORD_records_serialize(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, size_t dest_size, char *dest)
Serialize the given records to the given destination buffer.
int(* zone_to_name)(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Look for an existing PKEY delegation record for a given public key.
static int namestore_sqlite_zone_to_name(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Look for an existing PKEY delegation record for a given public key.
sqlite3_stmt * lookup_label
Precompiled SQL to lookup records based on label.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void database_shutdown(struct Plugin *plugin)
Shutdown database connection and associate data structures.
#define GNUNET_SQ_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
void * libgnunet_plugin_namestore_sqlite_done(void *cls)
Exit point from the plugin.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:681
#define GNUNET_SQ_result_spec_end
End of result parameter specification.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
void(* GNUNET_NAMESTORE_RecordIterator)(void *cls, uint64_t serial, const struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Function called for each matching record.
int GNUNET_GNSRECORD_records_deserialize(size_t len, const char *src, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *dest)
Deserialize the given records to the given destination.
#define GNUNET_SQ_result_spec_auto_from_type(dst)
We expect a fixed-size result, with size determined by the type of * dst
static int ret
Final status code.
Definition: gnunet-arm.c:89
Information needed to run a list of SQL statements using GNUNET_SQ_exec_statements().
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:46
struct GNUNET_SQ_PrepareStatement GNUNET_SQ_make_prepare(const char *sql, sqlite3_stmt **pstmt)
Create a struct GNUNET_SQ_PrepareStatement
Definition: sq_prepare.c:37
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
common internal definitions for namestore service
int GNUNET_SQ_extract_result(sqlite3_stmt *result, struct GNUNET_SQ_ResultSpec *rs)
Extract results from a query result according to the given specification.
Definition: sq.c:82
static char * zone
Name of the zone we manage.
void * cls
Closure to pass to all plugin functions.
static uint64_t record_count
Record count.
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_uint32(const uint32_t *x)
Generate query parameter for an uint32_t in host byte order.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
#define LOG_SQLITE(db, level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; on file &#39;file...
void GNUNET_SQ_cleanup_result(struct GNUNET_SQ_ResultSpec *rs)
Free all memory that was allocated in rs during GNUNET_SQ_extract_result().
Definition: sq.c:117
static int database_setup(struct Plugin *plugin)
Initialize the database connections and associated data structures (create tables and indices as need...
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
int GNUNET_SQ_exec_statements(sqlite3 *dbh, const struct GNUNET_SQ_ExecuteStatement *es)
Request execution of an array of statements es from Postgres.
Definition: sq_exec.c:77
#define GNUNET_GNSRECORD_TYPE_PKEY
Record type for GNS zone transfer ("PKEY").
struct GNUNET_SQ_ExecuteStatement GNUNET_SQ_make_execute(const char *sql)
Create a struct GNUNET_SQ_ExecuteStatement where errors are fatal.
Definition: sq_exec.c:36
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_variable_size(void **dst, size_t *sptr)
Variable-size result expected.
static int result
Global testing status.
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_CRYPTO_EcdsaPublicKey *z)
Convert a zone key to a string (for printing debug messages).
int GNUNET_SQ_bind(sqlite3_stmt *stmt, const struct GNUNET_SQ_QueryParam *params)
Execute binding operations for a prepared statement.
Definition: sq.c:37
#define LOG(kind,...)
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
sqlite3_stmt * store_records
Precompiled SQL to store records.
void * iter_cls
Iterator cls.
static int namestore_sqlite_lookup_records(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
void * libgnunet_plugin_namestore_sqlite_init(void *cls)
Entry point for the plugin.
helper functions for Sqlite3 DB interactions
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_string(const char *ptr)
Generate query parameter for a string.
Description of a DB query parameter.
Definition: gnunet_sq_lib.h:54
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_uint64(uint64_t *u64)
uint64_t expected.
#define BUSY_TIMEOUT_MS
After how many ms "busy" should a DB operation fail for good? A low value makes sure that we are more...
char * fn
Filename used for the DB.
#define GNUNET_SQ_PREPARE_END
Terminator for executable statement list.
void GNUNET_SQ_reset(sqlite3 *dbh, sqlite3_stmt *stmt)
Reset stmt and log error.
Definition: sq.c:132
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_uint64(const uint64_t *x)
Generate query parameter for an uint16_t in host byte order.
int(* lookup_records)(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
configuration data
Definition: configuration.c:83
Handle for a plugin.
Definition: block.c:37
PGconn * dbh
Native Postgres database handle.
sqlite3_stmt * delete_records
Precompiled SQL to deltete existing records.
int GNUNET_SQ_prepare(sqlite3 *dbh, const struct GNUNET_SQ_PrepareStatement *ps)
Prepare all statements given in the (NULL,NULL)-terminated array at ps.
Definition: sq_prepare.c:59
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_log(kind,...)
sqlite3_stmt * iterate_zone
Precompiled SQL for iterate records within a zone.
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_fixed_size(const void *ptr, size_t ptr_size)
Generate query parameter for a buffer ptr of ptr_size bytes.
#define GNUNET_SQ_query_param_end
End of query parameter specification.
Definition: gnunet_sq_lib.h:85
#define GNUNET_log_from(kind, comp,...)
sqlite3_stmt * zone_to_name
Precompiled SQL to for reverse lookup based on PKEY.
static int namestore_sqlite_store_records(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Store a record in the datastore.
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_string(char **dst)
0-terminated string expected.
uint32_t data
The data value.
int(* store_records)(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Store a record in the datastore for which we are the authority.
static size_t data_size
Number of bytes in data.
GNUNET_PEERSTORE_Processor iter
Iterator.
struct returned by the initialization function of the plugin
struct GNUNET_SQ_ExecuteStatement GNUNET_SQ_make_try_execute(const char *sql)
Create a struct GNUNET_SQ_ExecuteStatement where errors should be tolerated.
Definition: sq_exec.c:56
int(* iterate_records)(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, uint64_t serial, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Iterate over the results for a particular zone in the datastore.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_free(ptr)
Wrapper around free.