GNUnet  0.17.6
Data Structures | Macros | Functions
plugin_namestore_postgres.c File Reference

postgres-based namestore backend More...

#include "platform.h"
#include "gnunet_namestore_plugin.h"
#include "gnunet_namestore_service.h"
#include "gnunet_gnsrecord_lib.h"
#include "gnunet_pq_lib.h"
#include "namestore.h"
Include dependency graph for plugin_namestore_postgres.c:

Go to the source code of this file.

Data Structures

struct  Plugin
 Handle for a plugin. More...
 
struct  ParserContext
 Closure for parse_result_call_iterator. More...
 

Macros

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

Functions

static int init_database (struct Plugin *plugin, char **emsg, int drop)
 Initialize the database connections and associated data structures (create tables and indices as needed as well). More...
 
static int database_prepare (struct Plugin *plugin)
 
static int database_connect (struct Plugin *plugin)
 Initialize the database connections and associated data structures (create tables and indices as needed as well). More...
 
static int namestore_postgres_store_records (void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
 Store a record in the datastore. More...
 
static void parse_result_call_iterator (void *cls, PGresult *res, unsigned int num_results)
 A statement has been run. More...
 
static int lookup_records (void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls, const char *method)
 Lookup records in the datastore for which we are the authority. More...
 
static int namestore_postgres_lookup_records (void *cls, const struct GNUNET_IDENTITY_PrivateKey *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_postgres_edit_records (void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
 Edit records in the datastore for which we are the authority. More...
 
static int namestore_postgres_iterate_records (void *cls, const struct GNUNET_IDENTITY_PrivateKey *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_postgres_zone_to_name (void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const struct GNUNET_IDENTITY_PublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
 Look for an existing PKEY delegation record for a given public key. More...
 
static enum GNUNET_GenericReturnValue namestore_postgres_transaction_begin (void *cls, char **emsg)
 Begin a transaction for a client. More...
 
static enum GNUNET_GenericReturnValue namestore_postgres_transaction_rollback (void *cls, char **emsg)
 Commit a transaction for a client. More...
 
static enum GNUNET_GenericReturnValue namestore_postgres_transaction_commit (void *cls, char **emsg)
 Roll back a transaction for a client. More...
 
static enum GNUNET_GenericReturnValue namestore_postgres_initialize_database (void *cls, char **emsg)
 
static enum GNUNET_GenericReturnValue namestore_postgres_reset_database (void *cls, char **emsg)
 
static void database_shutdown (struct Plugin *plugin)
 Shutdown database connection and associate data structures. More...
 
void * libgnunet_plugin_namestore_postgres_init (void *cls)
 Entry point for the plugin. More...
 
void * libgnunet_plugin_namestore_postgres_done (void *cls)
 Exit point from the plugin. More...
 

Detailed Description

postgres-based namestore backend

Author
Christian Grothoff

Definition in file plugin_namestore_postgres.c.

Macro Definition Documentation

◆ LOG

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

Definition at line 34 of file plugin_namestore_postgres.c.

Function Documentation

◆ init_database()

static int init_database ( struct Plugin plugin,
char **  emsg,
int  drop 
)
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 68 of file plugin_namestore_postgres.c.

69 {
70  struct GNUNET_PQ_ExecuteStatement es_temporary =
72  "CREATE TEMPORARY TABLE ns098records ("
73  " seq BIGSERIAL PRIMARY KEY,"
74  " zone_private_key BYTEA NOT NULL DEFAULT '',"
75  " pkey BYTEA DEFAULT '',"
76  " rvalue BYTEA NOT NULL DEFAULT '',"
77  " record_count INTEGER NOT NULL DEFAULT 0,"
78  " record_data BYTEA NOT NULL DEFAULT '',"
79  " label TEXT NOT NULL DEFAULT '',"
80  " CONSTRAINT zl UNIQUE (zone_private_key,label)"
81  ")");
82  struct GNUNET_PQ_ExecuteStatement es_default =
83  GNUNET_PQ_make_execute ("CREATE TABLE ns098records ("
84  " seq BIGSERIAL PRIMARY KEY,"
85  " zone_private_key BYTEA NOT NULL DEFAULT '',"
86  " pkey BYTEA DEFAULT '',"
87  " rvalue BYTEA NOT NULL DEFAULT '',"
88  " record_count INTEGER NOT NULL DEFAULT 0,"
89  " record_data BYTEA NOT NULL DEFAULT '',"
90  " label TEXT NOT NULL DEFAULT '',"
91  " CONSTRAINT zl UNIQUE (zone_private_key,label)"
92  ")");
93  const struct GNUNET_PQ_ExecuteStatement *cr;
95  struct GNUNET_PQ_ExecuteStatement es_drop =
96  GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS ns098records");
97  if (GNUNET_YES ==
99  "namestore-postgres",
100  "TEMPORARY_TABLE"))
101  cr = &es_temporary;
102  else
103  cr = &es_default;
104 
105  if (GNUNET_YES ==
107  "namestore-postgres",
108  "ASYNC_COMMIT"))
109  sc = GNUNET_PQ_make_try_execute ("SET synchronous_commit TO off");
110 
111  {
112  struct GNUNET_PQ_ExecuteStatement es[] = {
113  *cr,
114  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_reverse "
115  "ON ns098records (zone_private_key,pkey)"),
116  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_iter "
117  "ON ns098records (zone_private_key,seq)"),
118  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_label "
119  "ON ns098records (label)"),
120  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS zone_label "
121  "ON ns098records (zone_private_key,label)"),
122  sc,
124  };
125  struct GNUNET_PQ_ExecuteStatement es_alt[] = {
126  es_drop,
127  *cr,
128  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_reverse "
129  "ON ns098records (zone_private_key,pkey)"),
130  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_iter "
131  "ON ns098records (zone_private_key,seq)"),
132  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_label "
133  "ON ns098records (label)"),
134  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS zone_label "
135  "ON ns098records (zone_private_key,label)"),
136  sc,
138  };
139  if (GNUNET_NO == drop)
140  {
142  "namestore-postgres",
143  NULL,
144  es,
145  NULL);
146  }
147  else {
149  "namestore-postgres",
150  NULL,
151  es_alt,
152  NULL);
153  }
154  }
155  if (NULL == plugin->dbh)
156  {
157  *emsg = GNUNET_strdup ("Failed to connect to PQ database");
158  return GNUNET_SYSERR;
159  }
161  plugin->dbh = NULL;
162  return GNUNET_OK;
163 }
struct Plugin * plugin
The process handle to the testbed service.
static struct GNUNET_FS_SearchContext * sc
Definition: gnunet-search.c:84
struct GNUNET_PQ_ExecuteStatement GNUNET_PQ_make_execute(const char *sql)
Create a struct GNUNET_PQ_ExecuteStatement where errors are fatal.
Definition: pq_exec.c:36
void GNUNET_PQ_disconnect(struct GNUNET_PQ_Context *db)
Disconnect from the database, destroying the prepared statements and releasing other associated resou...
Definition: pq_connect.c:526
struct GNUNET_PQ_Context * GNUNET_PQ_connect_with_cfg(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *load_path_suffix, const struct GNUNET_PQ_ExecuteStatement *es, const struct GNUNET_PQ_PreparedStatement *ps)
Connect to a postgres database using the configuration option "CONFIG" in section.
Definition: pq_connect.c:461
struct GNUNET_PQ_ExecuteStatement GNUNET_PQ_make_try_execute(const char *sql)
Create a struct GNUNET_PQ_ExecuteStatement where errors should be tolerated.
Definition: pq_exec.c:55
#define GNUNET_PQ_EXECUTE_STATEMENT_END
Terminator for executable statement list.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
@ GNUNET_OK
Definition: gnunet_common.h:99
@ GNUNET_YES
@ GNUNET_NO
Definition: gnunet_common.h:98
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
Information needed to run a list of SQL statements using GNUNET_PQ_exec_statements().
struct GNUNET_PQ_Context * dbh
Native Postgres database handle.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.

References Plugin::cfg, Plugin::dbh, GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_NO, GNUNET_OK, GNUNET_PQ_connect_with_cfg(), GNUNET_PQ_disconnect(), GNUNET_PQ_EXECUTE_STATEMENT_END, GNUNET_PQ_make_execute(), GNUNET_PQ_make_try_execute(), GNUNET_strdup, GNUNET_SYSERR, GNUNET_YES, plugin, and sc.

Referenced by database_connect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ database_prepare()

static int database_prepare ( struct Plugin plugin)
static

Definition at line 166 of file plugin_namestore_postgres.c.

167 {
169  if (GNUNET_YES == plugin->ready)
170  return GNUNET_OK;
171  struct GNUNET_PQ_PreparedStatement ps[] = {
172  GNUNET_PQ_make_prepare ("store_records",
173  "INSERT INTO ns098records"
174  " (zone_private_key, pkey, rvalue, record_count, record_data, label)"
175  " VALUES ($1, $2, $3, $4, $5, $6)"
176  " ON CONFLICT ON CONSTRAINT zl"
177  " DO UPDATE"
178  " SET pkey=$2,rvalue=$3,record_count=$4,record_data=$5"
179  " WHERE ns098records.zone_private_key = $1"
180  " AND ns098records.label = $6",
181  6),
182  GNUNET_PQ_make_prepare ("delete_records",
183  "DELETE FROM ns098records "
184  "WHERE zone_private_key=$1 AND label=$2",
185  2),
186  GNUNET_PQ_make_prepare ("zone_to_name",
187  "SELECT seq,record_count,record_data,label FROM ns098records"
188  " WHERE zone_private_key=$1 AND pkey=$2",
189  2),
190  GNUNET_PQ_make_prepare ("iterate_zone",
191  "SELECT seq,record_count,record_data,label FROM ns098records "
192  "WHERE zone_private_key=$1 AND seq > $2 ORDER BY seq ASC LIMIT $3",
193  3),
194  GNUNET_PQ_make_prepare ("iterate_all_zones",
195  "SELECT seq,record_count,record_data,label,zone_private_key"
196  " FROM ns098records WHERE seq > $1 ORDER BY seq ASC LIMIT $2",
197  2),
198  GNUNET_PQ_make_prepare ("lookup_label",
199  "SELECT seq,record_count,record_data,label "
200  "FROM ns098records WHERE zone_private_key=$1 AND label=$2",
201  2),
202  GNUNET_PQ_make_prepare ("edit_set",
203  "SELECT seq,record_count,record_data,label "
204  "FROM ns098records WHERE zone_private_key=$1 AND label=$2 FOR UPDATE NOWAIT",
205  2),
207  };
209  if (GNUNET_OK != ret)
210  return ret;
212  return GNUNET_OK;
213 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
struct GNUNET_PQ_PreparedStatement GNUNET_PQ_make_prepare(const char *name, const char *sql, unsigned int num_args)
Create a struct GNUNET_PQ_PreparedStatement.
Definition: pq_prepare.c:38
enum GNUNET_GenericReturnValue GNUNET_PQ_prepare_statements(struct GNUNET_PQ_Context *db, const struct GNUNET_PQ_PreparedStatement *ps)
Request creation of prepared statements ps from Postgres.
Definition: pq_prepare.c:62
#define GNUNET_PQ_PREPARED_STATEMENT_END
Terminator for prepared statement list.
GNUNET_GenericReturnValue
Named constants for return values.
Definition: gnunet_common.h:96
Information needed to prepare a list of SQL statements using GNUNET_PQ_prepare_statements().
int ready
Database is prepared and ready.

References Plugin::dbh, GNUNET_OK, GNUNET_PQ_make_prepare(), GNUNET_PQ_prepare_statements(), GNUNET_PQ_PREPARED_STATEMENT_END, GNUNET_YES, plugin, Plugin::ready, and ret.

Referenced by lookup_records(), namestore_postgres_initialize_database(), namestore_postgres_iterate_records(), and namestore_postgres_store_records().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ database_connect()

static int database_connect ( 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

Gracefully fail as this should not be a critical error if the database is already created

Definition at line 225 of file plugin_namestore_postgres.c.

226 {
227  const struct GNUNET_PQ_ExecuteStatement *cr;
228  char *emsg;
230 
231  if (GNUNET_YES ==
233  "namestore-postgres",
234  "INIT_ON_CONNECT"))
235  {
240  if (GNUNET_OK != init_database (plugin, &emsg, GNUNET_NO))
241  {
243  "Failed to initialize database on connect: `%s'\n",
244  emsg);
245  GNUNET_free (emsg);
246  }
247  }
249  "namestore-postgres",
250  NULL,
251  NULL,
252  NULL);
253  if (NULL == plugin->dbh)
254  return GNUNET_SYSERR;
255  return GNUNET_OK;
256 }
@ GNUNET_ERROR_TYPE_WARNING
#define GNUNET_free(ptr)
Wrapper around free.
static int init_database(struct Plugin *plugin, char **emsg, int drop)
Initialize the database connections and associated data structures (create tables and indices as need...
#define LOG(kind,...)

References Plugin::cfg, Plugin::dbh, GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_NO, GNUNET_OK, GNUNET_PQ_connect_with_cfg(), GNUNET_PQ_EXECUTE_STATEMENT_END, GNUNET_SYSERR, GNUNET_YES, init_database(), LOG, plugin, and sc.

Referenced by libgnunet_plugin_namestore_postgres_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ namestore_postgres_store_records()

static int namestore_postgres_store_records ( void *  cls,
const struct GNUNET_IDENTITY_PrivateKey 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 271 of file plugin_namestore_postgres.c.

277 {
278  struct Plugin *plugin = cls;
280  uint64_t rvalue;
281  uint32_t rd_count32 = (uint32_t) rd_count;
282  ssize_t data_size;
283 
285  memset (&pkey,
286  0,
287  sizeof(pkey));
288  for (unsigned int i = 0; i < rd_count; i++)
289  if (GNUNET_YES ==
290  GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type))
291  {
294  rd[i].data_size,
295  rd[i].record_type,
296  &pkey));
297  break;
298  }
300  UINT64_MAX);
302  rd);
303  if (data_size < 0)
304  {
305  GNUNET_break (0);
306  return GNUNET_SYSERR;
307  }
308  if (data_size >= UINT16_MAX)
309  {
310  GNUNET_break (0);
311  return GNUNET_SYSERR;
312  }
313  /* if record set is empty, delete existing records */
314  if (0 == rd_count)
315  {
316  struct GNUNET_PQ_QueryParam params[] = {
320  };
322 
324  "delete_records",
325  params);
328  {
329  GNUNET_break (0);
330  return GNUNET_SYSERR;
331  }
333  "postgres",
334  "Record deleted\n");
335  return GNUNET_OK;
336  }
337  /* otherwise, UPSERT (i.e. UPDATE if exists, otherwise INSERT) */
338  {
339  char data[data_size];
340  struct GNUNET_PQ_QueryParam params[] = {
344  GNUNET_PQ_query_param_uint32 (&rd_count32),
348  };
350  ssize_t ret;
351 
353  rd,
354  data_size,
355  data);
356  if ((ret < 0) ||
357  (data_size != ret))
358  {
359  GNUNET_break (0);
360  return GNUNET_SYSERR;
361  }
362 
364  "store_records",
365  params);
367  return GNUNET_SYSERR;
368  }
369  return GNUNET_OK;
370 }
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
static int res
uint32_t data
The data value.
static char * pkey
Public key of the zone to look in, in ASCII.
static const struct GNUNET_IDENTITY_PrivateKey * zone_key
Private key of the zone.
GNUNET_DB_QueryStatus
Status code returned from functions running database commands.
Definition: gnunet_db_lib.h:36
@ GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
The transaction succeeded, and yielded one result.
Definition: gnunet_db_lib.h:59
@ GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
The transaction succeeded, but yielded zero results.
Definition: gnunet_db_lib.h:54
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_fixed_size(const void *ptr, size_t ptr_size)
Generate query parameter for a buffer ptr of ptr_size bytes.
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_uint64(const uint64_t *x)
Generate query parameter for an uint16_t in host byte order.
#define GNUNET_PQ_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.
#define GNUNET_PQ_query_param_end
End of query parameter specification.
Definition: gnunet_pq_lib.h:97
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_uint32(const uint32_t *x)
Generate query parameter for an uint32_t in host byte order.
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_prepared_non_select(struct GNUNET_PQ_Context *db, const char *statement_name, const struct GNUNET_PQ_QueryParam *params)
Execute a named prepared statement that is NOT a SELECT statement in connection using the given param...
Definition: pq_eval.c:164
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_string(const char *ptr)
Generate query parameter for a string.
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_identity_from_data(const char *data, size_t data_size, uint32_t type, struct GNUNET_IDENTITY_PublicKey *key)
Build a #GNUNET_GNSRECORD_PublicKey from zone delegation resource record data.
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.
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.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_is_zonekey_type(uint32_t type)
Check if this type is one of the supported GNS zone types.
#define GNUNET_log_from(kind, comp,...)
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_DEBUG
static int database_prepare(struct Plugin *plugin)
An identity key as per LSD0001.
Description of a DB query parameter.
Definition: gnunet_pq_lib.h:65
Handle for a plugin.
Definition: block.c:38

References data, data_size, database_prepare(), Plugin::dbh, GNUNET_assert, GNUNET_break, GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u64(), GNUNET_DB_STATUS_SUCCESS_NO_RESULTS, GNUNET_DB_STATUS_SUCCESS_ONE_RESULT, GNUNET_ERROR_TYPE_DEBUG, GNUNET_GNSRECORD_identity_from_data(), GNUNET_GNSRECORD_is_zonekey_type(), GNUNET_GNSRECORD_records_get_size(), GNUNET_GNSRECORD_records_serialize(), GNUNET_log_from, GNUNET_OK, GNUNET_PQ_eval_prepared_non_select(), GNUNET_PQ_query_param_auto_from_type, GNUNET_PQ_query_param_end, GNUNET_PQ_query_param_fixed_size(), GNUNET_PQ_query_param_string(), GNUNET_PQ_query_param_uint32(), GNUNET_PQ_query_param_uint64(), GNUNET_SYSERR, GNUNET_YES, pkey, plugin, res, ret, and zone_key.

Referenced by libgnunet_plugin_namestore_postgres_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_result_call_iterator()

static void parse_result_call_iterator ( void *  cls,
PGresult *  res,
unsigned int  num_results 
)
static

A statement has been run.

We should evaluate the result, and if possible call the iter in cls with the result.

Parameters
clsclosure of type struct ParserContext *
resultthe postgres result
num_resultthe number of results in result

Definition at line 410 of file plugin_namestore_postgres.c.

413 {
414  struct ParserContext *pc = cls;
415 
416  if (NULL == pc->iter)
417  return; /* no need to do more work */
419  "Got %d results from PQ.\n", num_results);
420  for (unsigned int i = 0; i < num_results; i++)
421  {
422  uint64_t serial;
423  void *data;
424  size_t data_size;
425  uint32_t record_count;
426  char *label;
427  struct GNUNET_IDENTITY_PrivateKey zk;
428  struct GNUNET_PQ_ResultSpec rs_with_zone[] = {
429  GNUNET_PQ_result_spec_uint64 ("seq", &serial),
430  GNUNET_PQ_result_spec_uint32 ("record_count", &record_count),
432  GNUNET_PQ_result_spec_string ("label", &label),
433  GNUNET_PQ_result_spec_auto_from_type ("zone_private_key", &zk),
435  };
436  struct GNUNET_PQ_ResultSpec rs_without_zone[] = {
437  GNUNET_PQ_result_spec_uint64 ("seq", &serial),
438  GNUNET_PQ_result_spec_uint32 ("record_count", &record_count),
440  GNUNET_PQ_result_spec_string ("label", &label),
442  };
443  struct GNUNET_PQ_ResultSpec *rs;
444 
445  rs = (NULL == pc->zone_key) ? rs_with_zone : rs_without_zone;
446  if (GNUNET_YES !=
448  rs,
449  i))
450  {
451  GNUNET_break (0);
452  return;
453  }
454 
455  if (record_count > 64 * 1024)
456  {
457  /* sanity check, don't stack allocate far too much just
458  because database might contain a large value here */
459  GNUNET_break (0);
461  return;
462  }
463 
464  {
466 
467  GNUNET_assert (0 != serial);
468  if (GNUNET_OK !=
470  data,
471  record_count,
472  rd))
473  {
474  GNUNET_break (0);
476  return;
477  }
478  pc->iter (pc->iter_cls,
479  serial,
480  (NULL == pc->zone_key) ? &zk : pc->zone_key,
481  label,
482  record_count,
483  rd);
484  }
486  }
487  pc->limit -= num_results;
488 }
static uint64_t record_count
Record count.
static struct GNUNET_FS_PublishContext * pc
Handle to FS-publishing operation.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_uint32(const char *name, uint32_t *u32)
uint32_t expected.
#define GNUNET_PQ_result_spec_auto_from_type(name, dst)
We expect a fixed-size result, with size determined by the type of * dst
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_uint64(const char *name, uint64_t *u64)
uint64_t expected.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_string(const char *name, char **dst)
0-terminated string expected.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_variable_size(const char *name, void **dst, size_t *sptr)
Variable-size result expected.
void GNUNET_PQ_cleanup_result(struct GNUNET_PQ_ResultSpec *rs)
Free all memory that was allocated in rs during GNUNET_PQ_extract_result().
Definition: pq.c:122
enum GNUNET_GenericReturnValue GNUNET_PQ_extract_result(PGresult *result, struct GNUNET_PQ_ResultSpec *rs, int row)
Extract results from a query result according to the given specification.
Definition: pq.c:132
#define GNUNET_PQ_result_spec_end
End of result parameter specification.
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_NZL(l)
Macro used to avoid using 0 for the length of a variable-size array (Non-Zero-Length).
A private key for an identity as per LSD0001.
Description of a DB result cell.
Closure for parse_result_call_iterator.

References data, data_size, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_GNSRECORD_records_deserialize(), GNUNET_NZL, GNUNET_OK, GNUNET_PQ_cleanup_result(), GNUNET_PQ_extract_result(), GNUNET_PQ_result_spec_auto_from_type, GNUNET_PQ_result_spec_end, GNUNET_PQ_result_spec_string(), GNUNET_PQ_result_spec_uint32(), GNUNET_PQ_result_spec_uint64(), GNUNET_PQ_result_spec_variable_size(), GNUNET_YES, LOG, pc, record_count, and res.

Referenced by lookup_records(), namestore_postgres_initialize_database(), and namestore_postgres_iterate_records().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ lookup_records()

static int lookup_records ( void *  cls,
const struct GNUNET_IDENTITY_PrivateKey zone,
const char *  label,
GNUNET_NAMESTORE_RecordIterator  iter,
void *  iter_cls,
const char *  method 
)
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
methodthe method to use "lookup_record" or "edit_set"
Returns
GNUNET_OK on success, GNUNET_NO for no results, else GNUNET_SYSERR

Definition at line 502 of file plugin_namestore_postgres.c.

509 {
510  struct Plugin *plugin = cls;
512  struct GNUNET_PQ_QueryParam params[] = {
516  };
517  struct ParserContext pc;
519 
520  if (NULL == zone)
521  {
522  GNUNET_break (0);
523  return GNUNET_SYSERR;
524  }
525  pc.iter = iter;
526  pc.iter_cls = iter_cls;
527  pc.zone_key = zone;
529  method,
530  params,
532  &pc);
533  if (res < 0)
534  return GNUNET_SYSERR;
536  return GNUNET_NO;
537  return GNUNET_OK;
538 }
static char * zone
Name of the zone being managed.
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_prepared_multi_select(struct GNUNET_PQ_Context *db, const char *statement_name, const struct GNUNET_PQ_QueryParam *params, GNUNET_PQ_PostgresResultHandler rh, void *rh_cls)
Execute a named prepared statement that is a SELECT statement which may return multiple results in co...
Definition: pq_eval.c:209
static void parse_result_call_iterator(void *cls, PGresult *res, unsigned int num_results)
A statement has been run.
void * iter_cls
Closure for iter.
GNUNET_NAMESTORE_RecordIterator iter
Function to call for each result.

References database_prepare(), Plugin::dbh, GNUNET_assert, GNUNET_break, GNUNET_DB_STATUS_SUCCESS_NO_RESULTS, GNUNET_NO, GNUNET_OK, GNUNET_PQ_eval_prepared_multi_select(), GNUNET_PQ_query_param_auto_from_type, GNUNET_PQ_query_param_end, GNUNET_PQ_query_param_string(), GNUNET_SYSERR, ParserContext::iter, ParserContext::iter_cls, parse_result_call_iterator(), pc, plugin, res, and zone.

Referenced by namestore_postgres_edit_records(), and namestore_postgres_lookup_records().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ namestore_postgres_lookup_records()

static int namestore_postgres_lookup_records ( void *  cls,
const struct GNUNET_IDENTITY_PrivateKey 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 551 of file plugin_namestore_postgres.c.

557 {
558  return lookup_records (cls, zone, label, iter, iter_cls, "lookup_label");
559 }
static int lookup_records(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls, const char *method)
Lookup records in the datastore for which we are the authority.

References ParserContext::iter, ParserContext::iter_cls, lookup_records(), and zone.

Referenced by libgnunet_plugin_namestore_postgres_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ namestore_postgres_edit_records()

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

Edit 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 572 of file plugin_namestore_postgres.c.

578 {
579  return lookup_records (cls, zone, label, iter, iter_cls, "edit_set");
580 }

References ParserContext::iter, ParserContext::iter_cls, lookup_records(), and zone.

Referenced by libgnunet_plugin_namestore_postgres_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ namestore_postgres_iterate_records()

static int namestore_postgres_iterate_records ( void *  cls,
const struct GNUNET_IDENTITY_PrivateKey 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 fetch
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 596 of file plugin_namestore_postgres.c.

603 {
604  struct Plugin *plugin = cls;
606  struct ParserContext pc;
607 
609  pc.iter = iter;
610  pc.iter_cls = iter_cls;
611  pc.zone_key = zone;
612  pc.limit = limit;
613  if (NULL == zone)
614  {
615  struct GNUNET_PQ_QueryParam params_without_zone[] = {
619  };
620 
622  "iterate_all_zones",
623  params_without_zone,
625  &pc);
626  }
627  else
628  {
629  struct GNUNET_PQ_QueryParam params_with_zone[] = {
634  };
635 
637  "iterate_zone",
638  params_with_zone,
640  &pc);
641  }
642  if (res < 0)
643  return GNUNET_SYSERR;
644 
646  (pc.limit > 0))
647  return GNUNET_NO;
648  return GNUNET_OK;
649 }
uint64_t limit
Number of results still to return (counted down by number of results given to iterator).

References database_prepare(), Plugin::dbh, GNUNET_assert, GNUNET_DB_STATUS_SUCCESS_NO_RESULTS, GNUNET_NO, GNUNET_OK, GNUNET_PQ_eval_prepared_multi_select(), GNUNET_PQ_query_param_auto_from_type, GNUNET_PQ_query_param_end, GNUNET_PQ_query_param_uint64(), GNUNET_SYSERR, ParserContext::iter, ParserContext::iter_cls, ParserContext::limit, parse_result_call_iterator(), pc, plugin, res, and zone.

Referenced by libgnunet_plugin_namestore_postgres_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ namestore_postgres_zone_to_name()

static int namestore_postgres_zone_to_name ( void *  cls,
const struct GNUNET_IDENTITY_PrivateKey zone,
const struct GNUNET_IDENTITY_PublicKey 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 664 of file plugin_namestore_postgres.c.

671 {
672  struct Plugin *plugin = cls;
674  struct GNUNET_PQ_QueryParam params[] = {
678  };
680  struct ParserContext pc;
681 
682  pc.iter = iter;
683  pc.iter_cls = iter_cls;
684  pc.zone_key = zone;
686  "zone_to_name",
687  params,
689  &pc);
690  if (res < 0)
691  return GNUNET_SYSERR;
692  return GNUNET_OK;
693 }

Referenced by libgnunet_plugin_namestore_postgres_init().

Here is the caller graph for this function:

◆ namestore_postgres_transaction_begin()

static enum GNUNET_GenericReturnValue namestore_postgres_transaction_begin ( void *  cls,
char **  emsg 
)
static

Begin a transaction for a client.

Parameters
clsclosure (internal context for the plugin)
emsgerror message set of return code is GNUNET_SYSERR
Returns
GNUNET_YES on success, GNUNET_SYSERR if transaction cannot be started.

Definition at line 664 of file plugin_namestore_postgres.c.

705 {
706  struct Plugin *plugin = cls;
708  struct GNUNET_PQ_ExecuteStatement es[] = {
709  GNUNET_PQ_make_execute ("BEGIN"),
711  };
712 
713  return GNUNET_PQ_exec_statements (plugin->dbh, es);
714 }
enum GNUNET_GenericReturnValue GNUNET_PQ_exec_statements(struct GNUNET_PQ_Context *db, const struct GNUNET_PQ_ExecuteStatement *es)
Request execution of an array of statements es from Postgres.
Definition: pq_exec.c:76

Referenced by libgnunet_plugin_namestore_postgres_init().

Here is the caller graph for this function:

◆ namestore_postgres_transaction_rollback()

static enum GNUNET_GenericReturnValue namestore_postgres_transaction_rollback ( void *  cls,
char **  emsg 
)
static

Commit a transaction for a client.

This releases the lock on the database.

Parameters
clsclosure (internal context for the plugin)
emsgerror message set of return code is GNUNET_SYSERR
Returns
GNUNET_YES on success, GNUNET_SYSERR if transaction cannot be started.

Definition at line 664 of file plugin_namestore_postgres.c.

727 {
728  struct Plugin *plugin = cls;
730  struct GNUNET_PQ_ExecuteStatement es[] = {
731  GNUNET_PQ_make_execute ("ROLLBACK"),
733  };
734 
735  return GNUNET_PQ_exec_statements (plugin->dbh, es);
736 }

Referenced by libgnunet_plugin_namestore_postgres_init().

Here is the caller graph for this function:

◆ namestore_postgres_transaction_commit()

static enum GNUNET_GenericReturnValue namestore_postgres_transaction_commit ( void *  cls,
char **  emsg 
)
static

Roll back a transaction for a client.

This releases the lock on the database.

Parameters
clsclosure (internal context for the plugin)
emsgerror message set of return code is GNUNET_SYSERR
Returns
GNUNET_YES on success, GNUNET_SYSERR if transaction cannot be started.

Definition at line 664 of file plugin_namestore_postgres.c.

749 {
750  struct Plugin *plugin = cls;
752  struct GNUNET_PQ_ExecuteStatement es[] = {
753  GNUNET_PQ_make_execute ("COMMIT"),
755  };
756 
757  return GNUNET_PQ_exec_statements (plugin->dbh, es);
758 }

Referenced by libgnunet_plugin_namestore_postgres_init().

Here is the caller graph for this function:

◆ namestore_postgres_initialize_database()

static enum GNUNET_GenericReturnValue namestore_postgres_initialize_database ( void *  cls,
char **  emsg 
)
static

Definition at line 664 of file plugin_namestore_postgres.c.

764 {
765  return init_database (cls, emsg, GNUNET_NO);
766 }

References database_prepare(), Plugin::dbh, GNUNET_assert, GNUNET_OK, GNUNET_PQ_eval_prepared_multi_select(), GNUNET_PQ_query_param_auto_from_type, GNUNET_PQ_query_param_end, GNUNET_SYSERR, ParserContext::iter, ParserContext::iter_cls, parse_result_call_iterator(), pc, plugin, res, and zone.

Referenced by libgnunet_plugin_namestore_postgres_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ namestore_postgres_reset_database()

static enum GNUNET_GenericReturnValue namestore_postgres_reset_database ( void *  cls,
char **  emsg 
)
static

Definition at line 664 of file plugin_namestore_postgres.c.

772 {
773  return init_database (cls, emsg, GNUNET_YES);
774 }

Referenced by libgnunet_plugin_namestore_postgres_init().

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 785 of file plugin_namestore_postgres.c.

786 {
788  plugin->dbh = NULL;
789 }

References Plugin::dbh, GNUNET_PQ_disconnect(), and plugin.

Referenced by libgnunet_plugin_namestore_postgres_done(), and libgnunet_plugin_namestore_postgres_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ libgnunet_plugin_namestore_postgres_init()

void* libgnunet_plugin_namestore_postgres_init ( void *  cls)

Entry point for the plugin.

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

Definition at line 799 of file plugin_namestore_postgres.c.

800 {
801  struct Plugin *plugin;
802  const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
804 
805  plugin = GNUNET_new (struct Plugin);
806  plugin->cfg = cfg;
808  {
811  return NULL;
812  }
814  api->cls = plugin;
826  "Postgres namestore plugin running\n");
827  return api;
828 }
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static enum GNUNET_GenericReturnValue namestore_postgres_transaction_begin(void *cls, char **emsg)
Begin a transaction for a client.
static enum GNUNET_GenericReturnValue namestore_postgres_initialize_database(void *cls, char **emsg)
static enum GNUNET_GenericReturnValue namestore_postgres_transaction_rollback(void *cls, char **emsg)
Commit a transaction for a client.
static void database_shutdown(struct Plugin *plugin)
Shutdown database connection and associate data structures.
static int namestore_postgres_zone_to_name(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const struct GNUNET_IDENTITY_PublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Look for an existing PKEY delegation record for a given public key.
static int namestore_postgres_iterate_records(void *cls, const struct GNUNET_IDENTITY_PrivateKey *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.
static int namestore_postgres_store_records(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Store a record in the datastore.
static enum GNUNET_GenericReturnValue namestore_postgres_reset_database(void *cls, char **emsg)
static int namestore_postgres_lookup_records(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
static int database_connect(struct Plugin *plugin)
Initialize the database connections and associated data structures (create tables and indices as need...
static int namestore_postgres_edit_records(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Edit records in the datastore for which we are the authority.
static enum GNUNET_GenericReturnValue namestore_postgres_transaction_commit(void *cls, char **emsg)
Roll back a transaction for a client.
struct returned by the initialization function of the plugin
int(* lookup_records)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
int(* zone_to_name)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const struct GNUNET_IDENTITY_PublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Look for an existing PKEY delegation record for a given public key.
int(* iterate_records)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *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.
enum GNUNET_GenericReturnValue(* transaction_begin)(void *cls, char **emsg)
Transaction-based API draft.
int(* store_records)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *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.
int(* reset_database)(void *cls, char **emsg)
Re-initializes the database.
enum GNUNET_GenericReturnValue(* transaction_commit)(void *cls, char **emsg)
Commit a transaction in the database.
void * cls
Closure to pass to all plugin functions.
int(* initialize_database)(void *cls, char **emsg)
Setup the database.
enum GNUNET_GenericReturnValue(* transaction_rollback)(void *cls, char **emsg)
Abort and roll back a transaction in the database.
int(* edit_records)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Edit records in the datastore for which we are the authority.

References cfg, Plugin::cfg, GNUNET_NAMESTORE_PluginFunctions::cls, database_connect(), database_shutdown(), GNUNET_NAMESTORE_PluginFunctions::edit_records, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_new, GNUNET_OK, GNUNET_NAMESTORE_PluginFunctions::initialize_database, GNUNET_NAMESTORE_PluginFunctions::iterate_records, LOG, GNUNET_NAMESTORE_PluginFunctions::lookup_records, namestore_postgres_edit_records(), namestore_postgres_initialize_database(), namestore_postgres_iterate_records(), namestore_postgres_lookup_records(), namestore_postgres_reset_database(), namestore_postgres_store_records(), namestore_postgres_transaction_begin(), namestore_postgres_transaction_commit(), namestore_postgres_transaction_rollback(), namestore_postgres_zone_to_name(), plugin, GNUNET_NAMESTORE_PluginFunctions::reset_database, GNUNET_NAMESTORE_PluginFunctions::store_records, GNUNET_NAMESTORE_PluginFunctions::transaction_begin, GNUNET_NAMESTORE_PluginFunctions::transaction_commit, GNUNET_NAMESTORE_PluginFunctions::transaction_rollback, and GNUNET_NAMESTORE_PluginFunctions::zone_to_name.

Here is the call graph for this function:

◆ libgnunet_plugin_namestore_postgres_done()

void* libgnunet_plugin_namestore_postgres_done ( void *  cls)

Exit point from the plugin.

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

Definition at line 838 of file plugin_namestore_postgres.c.

839 {
841  struct Plugin *plugin = api->cls;
842 
844  plugin->cfg = NULL;
846  GNUNET_free (api);
848  "Postgres namestore plugin is finished\n");
849  return NULL;
850 }
void * cls
Closure for all of the callbacks.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47

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

Here is the call graph for this function: