GNUnet  0.10.x
Data Structures | Macros | Functions
plugin_namestore_sqlite.c File Reference

sqlite-based namestore backend More...

#include "platform.h"
#include "gnunet_namestore_plugin.h"
#include "gnunet_namestore_service.h"
#include "gnunet_gnsrecord_lib.h"
#include "gnunet_sq_lib.h"
#include "namestore.h"
#include <sqlite3.h>
Include dependency graph for plugin_namestore_sqlite.c:

Go to the source code of this file.

Data Structures

struct  Plugin
 Handle for a plugin. More...
 

Macros

#define BUSY_TIMEOUT_MS   1000
 After how many ms "busy" should a DB operation fail for good? A low value makes sure that we are more responsive to requests (especially PUTs). More...
 
#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)
 Log an error message at log-level 'level' that indicates a failure of the command 'cmd' on file 'filename' with the message given by strerror(errno). More...
 
#define LOG(kind, ...)   GNUNET_log_from(kind, "namestore-sqlite", __VA_ARGS__)
 

Functions

static int database_setup (struct Plugin *plugin)
 Initialize the database connections and associated data structures (create tables and indices as needed as well). More...
 
static void database_shutdown (struct Plugin *plugin)
 Shutdown database connection and associate data structures. More...
 
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. More...
 
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 'sqlite' statement has been prepared to be run. More...
 
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. More...
 
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. More...
 
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. More...
 
void * libgnunet_plugin_namestore_sqlite_init (void *cls)
 Entry point for the plugin. More...
 
void * libgnunet_plugin_namestore_sqlite_done (void *cls)
 Exit point from the plugin. More...
 

Detailed Description

sqlite-based namestore backend

Author
Christian Grothoff

Definition in file plugin_namestore_sqlite.c.

Macro Definition Documentation

◆ BUSY_TIMEOUT_MS

#define BUSY_TIMEOUT_MS   1000

After how many ms "busy" should a DB operation fail for good? A low value makes sure that we are more responsive to requests (especially PUTs).

A high value guarantees a higher success rate (SELECTs in iterate can take several seconds despite LIMIT=1).

The default value of 1s should ensure that users do not experience huge latencies while at the same time allowing operations to succeed with reasonable probability.

Definition at line 45 of file plugin_namestore_sqlite.c.

Referenced by database_setup().

◆ LOG_SQLITE

#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)

Log an error message at log-level 'level' that indicates a failure of the command 'cmd' on file 'filename' with the message given by strerror(errno).

Definition at line 53 of file plugin_namestore_sqlite.c.

Referenced by database_shutdown(), get_records_and_call_iterator(), namestore_sqlite_iterate_records(), namestore_sqlite_lookup_records(), namestore_sqlite_store_records(), and namestore_sqlite_zone_to_name().

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from(kind, "namestore-sqlite", __VA_ARGS__)

Function Documentation

◆ database_setup()

static int database_setup ( struct Plugin plugin)
static

Initialize the database connections and associated data structures (create tables and indices as needed as well).

Parameters
pluginthe plugin context (state for this module)
Returns
GNUNET_OK on success

Definition at line 115 of file plugin_namestore_sqlite.c.

References _, BUSY_TIMEOUT_MS, Plugin::cfg, Plugin::dbh, Plugin::delete_records, Plugin::fn, GNUNET_break, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_DISK_directory_create_for_file(), GNUNET_DISK_file_test(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log_config_missing(), GNUNET_OK, GNUNET_SQ_exec_statements(), GNUNET_SQ_EXECUTE_STATEMENT_END, GNUNET_SQ_make_execute(), GNUNET_SQ_make_prepare(), GNUNET_SQ_make_try_execute(), GNUNET_SQ_prepare(), GNUNET_SQ_PREPARE_END, GNUNET_SYSERR, Plugin::iterate_all_zones, Plugin::iterate_zone, LOG, Plugin::lookup_label, Plugin::store_records, and Plugin::zone_to_name.

Referenced by libgnunet_plugin_namestore_sqlite_init().

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 }
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
sqlite3_stmt * iterate_all_zones
Precompiled SQL for iterate all records within all zones.
#define GNUNET_SQ_EXECUTE_STATEMENT_END
Terminator for executable statement list.
Information needed to run a list of SQL statements using GNUNET_SQ_exec_statements().
sqlite3_stmt * lookup_label
Precompiled SQL to lookup records based on label.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:681
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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_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
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
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
#define LOG(kind,...)
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
sqlite3_stmt * store_records
Precompiled SQL to store records.
#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.
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
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.
sqlite3_stmt * zone_to_name
Precompiled SQL to for reverse lookup based on PKEY.
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
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ database_shutdown()

static void database_shutdown ( struct Plugin plugin)
static

Shutdown database connection and associate data structures.

Parameters
pluginthe plugin context (state for this module)

Definition at line 242 of file plugin_namestore_sqlite.c.

References _, Plugin::dbh, Plugin::delete_records, Plugin::fn, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free_non_null, GNUNET_log_from, Plugin::iterate_all_zones, Plugin::iterate_zone, LOG, LOG_SQLITE, Plugin::lookup_label, result, Plugin::store_records, and Plugin::zone_to_name.

Referenced by libgnunet_plugin_namestore_sqlite_done(), and libgnunet_plugin_namestore_sqlite_init().

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 }
sqlite3_stmt * iterate_all_zones
Precompiled SQL for iterate all records within all zones.
sqlite3_stmt * lookup_label
Precompiled SQL to lookup records based on label.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
#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...
static int result
Global testing status.
#define LOG(kind,...)
sqlite3_stmt * store_records
Precompiled SQL to store records.
char * fn
Filename used for the DB.
PGconn * dbh
Native Postgres database handle.
sqlite3_stmt * delete_records
Precompiled SQL to deltete existing records.
sqlite3_stmt * iterate_zone
Precompiled SQL for iterate records within a zone.
#define GNUNET_log_from(kind, comp,...)
sqlite3_stmt * zone_to_name
Precompiled SQL to for reverse lookup based on PKEY.
Here is the caller graph for this function:

◆ namestore_sqlite_store_records()

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 
)
static

Store a record in the datastore.

Removes any existing record in the same zone with the same name.

Parameters
clsclosure (internal context for the plugin)
zone_keyprivate key of the zone
labelname that is being mapped (at most 255 characters long)
rd_countnumber of entries in rd array
rdarray of records with data to store
Returns
GNUNET_OK on success, else GNUNET_SYSERR

Definition at line 305 of file plugin_namestore_sqlite.c.

References data, data_size, Plugin::dbh, Plugin::delete_records, GNUNET_break, GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u64(), GNUNET_ERROR_TYPE_BULK, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_GNSRECORD_records_get_size(), GNUNET_GNSRECORD_records_serialize(), GNUNET_GNSRECORD_TYPE_PKEY, GNUNET_log_from, GNUNET_memcpy, GNUNET_NO, GNUNET_OK, GNUNET_SQ_bind(), GNUNET_SQ_query_param_auto_from_type, GNUNET_SQ_query_param_end, GNUNET_SQ_query_param_fixed_size(), GNUNET_SQ_query_param_string(), GNUNET_SQ_query_param_uint32(), GNUNET_SQ_query_param_uint64(), GNUNET_SQ_reset(), GNUNET_SYSERR, LOG_SQLITE, plugin, ret, and Plugin::store_records.

Referenced by libgnunet_plugin_namestore_sqlite_init().

310 {
311  struct Plugin *plugin = cls;
312  int n;
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);
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 }
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 char * pkey
Public key of the zone to look in, in ASCII.
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.
#define GNUNET_SQ_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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...
#define GNUNET_GNSRECORD_TYPE_PKEY
Record type for GNS zone transfer ("PKEY").
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 GNUNET_SYSERR
Definition: gnunet_common.h:76
sqlite3_stmt * store_records
Precompiled SQL to store records.
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
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.
Handle for a plugin.
Definition: block.c:37
PGconn * dbh
Native Postgres database handle.
sqlite3_stmt * delete_records
Precompiled SQL to deltete existing records.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
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,...)
uint32_t data
The data value.
static size_t data_size
Number of bytes in data.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_records_and_call_iterator()

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 
)
static

The given 'sqlite' statement has been prepared to be run.

It will return a record which should be given to the iterator. Runs the statement and parses the returned record.

Parameters
pluginplugin context
stmtto run (and then clean up)
zone_keyprivate key of the zone
limitmaximum number of results to fetch
iteriterator to call with the result
iter_clsclosure for iter
Returns
GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error

Definition at line 450 of file plugin_namestore_sqlite.c.

References data, data_size, Plugin::dbh, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_GNSRECORD_records_deserialize(), GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_SQ_cleanup_result(), GNUNET_SQ_extract_result(), GNUNET_SQ_reset(), GNUNET_SQ_result_spec_auto_from_type, GNUNET_SQ_result_spec_end, GNUNET_SQ_result_spec_string(), GNUNET_SQ_result_spec_uint32(), GNUNET_SQ_result_spec_uint64(), GNUNET_SQ_result_spec_variable_size(), GNUNET_SYSERR, Plugin::iter, LOG_SQLITE, record_count, and ret.

Referenced by namestore_sqlite_iterate_records(), namestore_sqlite_lookup_records(), and namestore_sqlite_zone_to_name().

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 }
Description of a DB result cell.
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_uint32(uint32_t *u32)
uint32_t expected.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#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
Private ECC key encoded for transmission.
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
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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 uint64_t record_count
Record count.
#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
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_variable_size(void **dst, size_t *sptr)
Variable-size result expected.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_uint64(uint64_t *u64)
uint64_t expected.
void GNUNET_SQ_reset(sqlite3 *dbh, sqlite3_stmt *stmt)
Reset stmt and log error.
Definition: sq.c:132
PGconn * dbh
Native Postgres database handle.
#define GNUNET_log(kind,...)
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_string(char **dst)
0-terminated string expected.
uint32_t data
The data value.
static size_t data_size
Number of bytes in data.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ namestore_sqlite_lookup_records()

static int namestore_sqlite_lookup_records ( void *  cls,
const struct GNUNET_CRYPTO_EcdsaPrivateKey zone,
const char *  label,
GNUNET_NAMESTORE_RecordIterator  iter,
void *  iter_cls 
)
static

Lookup records in the datastore for which we are the authority.

Parameters
clsclosure (internal context for the plugin)
zoneprivate key of the zone
labelname of the record in the zone
iterfunction to call with the result
iter_clsclosure for iter
Returns
GNUNET_OK on success, GNUNET_NO for no results, else GNUNET_SYSERR

Definition at line 567 of file plugin_namestore_sqlite.c.

References Plugin::dbh, get_records_and_call_iterator(), GNUNET_break, GNUNET_ERROR_TYPE_BULK, GNUNET_ERROR_TYPE_ERROR, GNUNET_OK, GNUNET_SQ_bind(), GNUNET_SQ_query_param_auto_from_type, GNUNET_SQ_query_param_end, GNUNET_SQ_query_param_string(), GNUNET_SQ_reset(), GNUNET_SYSERR, LOG_SQLITE, Plugin::lookup_label, and plugin.

Referenced by libgnunet_plugin_namestore_sqlite_init().

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 }
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 * lookup_label
Precompiled SQL to lookup records based on label.
#define GNUNET_SQ_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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...
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 GNUNET_SYSERR
Definition: gnunet_common.h:76
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
void GNUNET_SQ_reset(sqlite3 *dbh, sqlite3_stmt *stmt)
Reset stmt and log error.
Definition: sq.c:132
Handle for a plugin.
Definition: block.c:37
PGconn * dbh
Native Postgres database handle.
#define GNUNET_SQ_query_param_end
End of query parameter specification.
Definition: gnunet_sq_lib.h:85
Here is the call graph for this function:
Here is the caller graph for this function:

◆ namestore_sqlite_iterate_records()

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 
)
static

Iterate over the results for a particular key and zone in the datastore.

Will return at most one result to the iterator.

Parameters
clsclosure (internal context for the plugin)
zonehash of public key of the zone, NULL to iterate over all zones
serialserial number to exclude in the list of all matching records
limitmaximum number of results to return
iterfunction to call with the result
iter_clsclosure for iter
Returns
GNUNET_OK on success, GNUNET_NO if there were no more results, GNUNET_SYSERR on error

Definition at line 617 of file plugin_namestore_sqlite.c.

References Plugin::dbh, get_records_and_call_iterator(), GNUNET_ERROR_TYPE_BULK, GNUNET_ERROR_TYPE_ERROR, GNUNET_OK, GNUNET_SQ_bind(), GNUNET_SQ_query_param_auto_from_type, GNUNET_SQ_query_param_end, GNUNET_SQ_query_param_uint64(), GNUNET_SQ_reset(), GNUNET_SYSERR, Plugin::iterate_all_zones, Plugin::iterate_zone, LOG_SQLITE, and plugin.

Referenced by libgnunet_plugin_namestore_sqlite_init().

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 }
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.
#define GNUNET_SQ_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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...
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 GNUNET_SYSERR
Definition: gnunet_common.h:76
Description of a DB query parameter.
Definition: gnunet_sq_lib.h:54
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.
Handle for a plugin.
Definition: block.c:37
PGconn * dbh
Native Postgres database handle.
sqlite3_stmt * iterate_zone
Precompiled SQL for iterate records within a zone.
#define GNUNET_SQ_query_param_end
End of query parameter specification.
Definition: gnunet_sq_lib.h:85
Here is the call graph for this function:
Here is the caller graph for this function:

◆ namestore_sqlite_zone_to_name()

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 
)
static

Look for an existing PKEY delegation record for a given public key.

Returns at most one result to the iterator.

Parameters
clsclosure (internal context for the plugin)
zoneprivate key of the zone to look up in, never NULL
value_zonepublic key of the target zone (value), never NULL
iterfunction to call with the result
iter_clsclosure for iter
Returns
GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error

Definition at line 683 of file plugin_namestore_sqlite.c.

References Plugin::dbh, get_records_and_call_iterator(), GNUNET_ERROR_TYPE_BULK, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_GNSRECORD_z2s(), GNUNET_OK, GNUNET_SQ_bind(), GNUNET_SQ_query_param_auto_from_type, GNUNET_SQ_query_param_end, GNUNET_SQ_reset(), GNUNET_SYSERR, LOG, LOG_SQLITE, plugin, and Plugin::zone_to_name.

Referenced by libgnunet_plugin_namestore_sqlite_init().

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 }
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.
#define GNUNET_SQ_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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...
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
Description of a DB query parameter.
Definition: gnunet_sq_lib.h:54
void GNUNET_SQ_reset(sqlite3 *dbh, sqlite3_stmt *stmt)
Reset stmt and log error.
Definition: sq.c:132
Handle for a plugin.
Definition: block.c:37
PGconn * dbh
Native Postgres database handle.
#define GNUNET_SQ_query_param_end
End of query parameter specification.
Definition: gnunet_sq_lib.h:85
sqlite3_stmt * zone_to_name
Precompiled SQL to for reverse lookup based on PKEY.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ libgnunet_plugin_namestore_sqlite_init()

void* libgnunet_plugin_namestore_sqlite_init ( void *  cls)

Entry point for the plugin.

Parameters
clsthe "struct GNUNET_NAMESTORE_PluginEnvironment*"
Returns
NULL on error, otherwise the plugin context

Definition at line 726 of file plugin_namestore_sqlite.c.

References _, Plugin::api, Plugin::cfg, GNUNET_NAMESTORE_PluginFunctions::cls, database_setup(), database_shutdown(), GNUNET_ERROR_TYPE_INFO, GNUNET_new, GNUNET_OK, GNUNET_NAMESTORE_PluginFunctions::iterate_records, LOG, GNUNET_NAMESTORE_PluginFunctions::lookup_records, namestore_sqlite_iterate_records(), namestore_sqlite_lookup_records(), namestore_sqlite_store_records(), namestore_sqlite_zone_to_name(), plugin, GNUNET_NAMESTORE_PluginFunctions::store_records, and GNUNET_NAMESTORE_PluginFunctions::zone_to_name.

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;
739  {
741  return NULL;
742  }
744  api->cls = &plugin;
750  _("Sqlite database running\n"));
751  return api;
752 }
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.
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.
static void database_shutdown(struct Plugin *plugin)
Shutdown database connection and associate data structures.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
void * cls
Closure to pass to all plugin functions.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
static int database_setup(struct Plugin *plugin)
Initialize the database connections and associated data structures (create tables and indices as need...
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
#define LOG(kind,...)
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.
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
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.
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.
struct returned by the initialization function of the plugin
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.
Here is the call graph for this function:

◆ libgnunet_plugin_namestore_sqlite_done()

void* libgnunet_plugin_namestore_sqlite_done ( void *  cls)

Exit point from the plugin.

Parameters
clsthe plugin context (as returned by "init")
Returns
always NULL

Definition at line 762 of file plugin_namestore_sqlite.c.

References Plugin::api, Plugin::cfg, GNUNET_NAMESTORE_PluginFunctions::cls, database_shutdown(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, LOG, and plugin.

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 }
static void database_shutdown(struct Plugin *plugin)
Shutdown database connection and associate data structures.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
void * cls
Closure to pass to all plugin functions.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
#define LOG(kind,...)
Handle for a plugin.
Definition: block.c:37
struct returned by the initialization function of the plugin
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function: