GNUnet  0.11.x
Data Structures | Macros | Functions
plugin_namecache_postgres.c File Reference

postgres-based namecache backend More...

#include "platform.h"
#include "gnunet_namecache_plugin.h"
#include "gnunet_namecache_service.h"
#include "gnunet_gnsrecord_lib.h"
#include "gnunet_pq_lib.h"
#include "namecache.h"
Include dependency graph for plugin_namecache_postgres.c:

Go to the source code of this file.

Data Structures

struct  Plugin
 Handle for a plugin. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "namecache-postgres", __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 namecache_postgres_expire_blocks (struct Plugin *plugin)
 Removes any expired block. More...
 
static void delete_old_block (struct Plugin *plugin, const struct GNUNET_HashCode *query, struct GNUNET_TIME_Absolute expiration_time)
 Delete older block in the datastore. More...
 
static int namecache_postgres_cache_block (void *cls, const struct GNUNET_GNSRECORD_Block *block)
 Cache a block in the datastore. More...
 
static int namecache_postgres_lookup_block (void *cls, const struct GNUNET_HashCode *query, GNUNET_NAMECACHE_BlockCallback iter, void *iter_cls)
 Get the block for a particular zone and label in the datastore. More...
 
static void database_shutdown (struct Plugin *plugin)
 Shutdown database connection and associate data structures. More...
 
void * libgnunet_plugin_namecache_postgres_init (void *cls)
 Entry point for the plugin. More...
 
void * libgnunet_plugin_namecache_postgres_done (void *cls)
 Exit point from the plugin. More...
 

Detailed Description

postgres-based namecache backend

Author
Christian Grothoff

Definition in file plugin_namecache_postgres.c.

Macro Definition Documentation

◆ LOG

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

Definition at line 34 of file plugin_namecache_postgres.c.

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 60 of file plugin_namecache_postgres.c.

61 {
62  struct GNUNET_PQ_ExecuteStatement es_temporary =
63  GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS ns096blocks ("
64  " query BYTEA NOT NULL DEFAULT '',"
65  " block BYTEA NOT NULL DEFAULT '',"
66  " expiration_time BIGINT NOT NULL DEFAULT 0"
67  ")");
68  struct GNUNET_PQ_ExecuteStatement es_default =
69  GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS ns096blocks ("
70  " query BYTEA NOT NULL DEFAULT '',"
71  " block BYTEA NOT NULL DEFAULT '',"
72  " expiration_time BIGINT NOT NULL DEFAULT 0"
73  ")");
74  const struct GNUNET_PQ_ExecuteStatement *cr;
75 
76  if (GNUNET_YES ==
78  "namecache-postgres",
79  "TEMPORARY_TABLE"))
80  {
81  cr = &es_temporary;
82  }
83  else
84  {
85  cr = &es_default;
86  }
87  {
88  struct GNUNET_PQ_ExecuteStatement es[] = {
89  *cr,
91  "CREATE INDEX ir_query_hash ON ns096blocks (query,expiration_time)"),
93  "CREATE INDEX ir_block_expiration ON ns096blocks (expiration_time)"),
95  };
96  struct GNUNET_PQ_PreparedStatement ps[] = {
97  GNUNET_PQ_make_prepare ("cache_block",
98  "INSERT INTO ns096blocks (query, block, expiration_time) VALUES "
99  "($1, $2, $3)", 3),
100  GNUNET_PQ_make_prepare ("expire_blocks",
101  "DELETE FROM ns096blocks WHERE expiration_time<$1",
102  1),
103  GNUNET_PQ_make_prepare ("delete_block",
104  "DELETE FROM ns096blocks WHERE query=$1 AND expiration_time<=$2",
105  2),
106  GNUNET_PQ_make_prepare ("lookup_block",
107  "SELECT block FROM ns096blocks WHERE query=$1"
108  " ORDER BY expiration_time DESC LIMIT 1", 1),
110  };
111 
113  "namecache-postgres",
114  NULL,
115  es,
116  ps);
117  }
118  if (NULL == plugin->dbh)
119  return GNUNET_SYSERR;
120  return GNUNET_OK;
121 }
struct Plugin * plugin
The process handle to the testbed service.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
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
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
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:449
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_PREPARED_STATEMENT_END
Terminator for prepared statement list.
#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".
Information needed to run a list of SQL statements using GNUNET_PQ_exec_statements().
Information needed to prepare a list of SQL statements using GNUNET_PQ_prepare_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_OK, GNUNET_PQ_connect_with_cfg(), GNUNET_PQ_EXECUTE_STATEMENT_END, GNUNET_PQ_make_execute(), GNUNET_PQ_make_prepare(), GNUNET_PQ_make_try_execute(), GNUNET_PQ_PREPARED_STATEMENT_END, GNUNET_SYSERR, GNUNET_YES, and plugin.

Referenced by libgnunet_plugin_namecache_postgres_init().

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

◆ namecache_postgres_expire_blocks()

static void namecache_postgres_expire_blocks ( struct Plugin plugin)
static

Removes any expired block.

Parameters
pluginthe plugin

Definition at line 130 of file plugin_namecache_postgres.c.

131 {
133  struct GNUNET_PQ_QueryParam params[] = {
136  };
138 
140  "expire_blocks",
141  params);
143 }
static int res
GNUNET_DB_QueryStatus
Status code returned from functions running database commands.
Definition: gnunet_db_lib.h:36
@ GNUNET_DB_STATUS_HARD_ERROR
A hard error occurred, retrying will not help.
Definition: gnunet_db_lib.h:40
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_absolute_time(const struct GNUNET_TIME_Absolute *x)
Generate query parameter for an absolute time value.
#define GNUNET_PQ_query_param_end
End of query parameter specification.
Definition: gnunet_pq_lib.h:97
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
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:86
Description of a DB query parameter.
Definition: gnunet_pq_lib.h:65
Time for absolute times used by GNUnet, in microseconds.

References Plugin::dbh, GNUNET_break, GNUNET_DB_STATUS_HARD_ERROR, GNUNET_PQ_eval_prepared_non_select(), GNUNET_PQ_query_param_absolute_time(), GNUNET_PQ_query_param_end, GNUNET_TIME_absolute_get(), plugin, and res.

Referenced by namecache_postgres_cache_block().

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

◆ delete_old_block()

static void delete_old_block ( struct Plugin plugin,
const struct GNUNET_HashCode query,
struct GNUNET_TIME_Absolute  expiration_time 
)
static

Delete older block in the datastore.

Parameters
pluginthe plugin
queryquery for the block
expiration_timehow old does the block have to be for deletion

Definition at line 154 of file plugin_namecache_postgres.c.

157 {
158  struct GNUNET_PQ_QueryParam params[] = {
160  GNUNET_PQ_query_param_absolute_time (&expiration_time),
162  };
164 
166  "delete_block",
167  params);
169 }
#define GNUNET_PQ_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.

References Plugin::dbh, GNUNET_break, GNUNET_DB_STATUS_HARD_ERROR, GNUNET_PQ_eval_prepared_non_select(), GNUNET_PQ_query_param_absolute_time(), GNUNET_PQ_query_param_auto_from_type, GNUNET_PQ_query_param_end, plugin, and res.

Referenced by namecache_postgres_cache_block().

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

◆ namecache_postgres_cache_block()

static int namecache_postgres_cache_block ( void *  cls,
const struct GNUNET_GNSRECORD_Block block 
)
static

Cache a block in the datastore.

Parameters
clsclosure (internal context for the plugin)
blockblock to cache
Returns
GNUNET_OK on success, else GNUNET_SYSERR

Definition at line 180 of file plugin_namecache_postgres.c.

182 {
183  struct Plugin *plugin = cls;
184  struct GNUNET_HashCode query;
185  size_t block_size = GNUNET_GNSRECORD_block_get_size (block);
186  struct GNUNET_TIME_Absolute exp;
188  struct GNUNET_PQ_QueryParam params[] = {
190  GNUNET_PQ_query_param_fixed_size (block, block_size),
193  };
195 
198  &query);
199  if (block_size > 64 * 65536)
200  {
201  GNUNET_break (0);
202  return GNUNET_SYSERR;
203  }
205  &query,
206  exp);
207 
209  "cache_block",
210  params);
211  if (0 > res)
212  return GNUNET_SYSERR;
213  return GNUNET_OK;
214 }
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.
size_t GNUNET_GNSRECORD_block_get_size(const struct GNUNET_GNSRECORD_Block *block)
Returns the length of this block in bytes.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_query_from_block(const struct GNUNET_GNSRECORD_Block *block, struct GNUNET_HashCode *query)
Builds the query hash from a block.
struct GNUNET_TIME_Absolute GNUNET_GNSRECORD_block_get_expiration(const struct GNUNET_GNSRECORD_Block *block)
Returns the expiration of a block.
static void delete_old_block(struct Plugin *plugin, const struct GNUNET_HashCode *query, struct GNUNET_TIME_Absolute expiration_time)
Delete older block in the datastore.
static void namecache_postgres_expire_blocks(struct Plugin *plugin)
Removes any expired block.
A 512-bit hashcode.
Handle for a plugin.
Definition: block.c:38

References Plugin::dbh, delete_old_block(), GNUNET_break, GNUNET_GNSRECORD_block_get_expiration(), GNUNET_GNSRECORD_block_get_size(), GNUNET_GNSRECORD_query_from_block(), GNUNET_OK, GNUNET_PQ_eval_prepared_non_select(), GNUNET_PQ_query_param_absolute_time(), GNUNET_PQ_query_param_auto_from_type, GNUNET_PQ_query_param_end, GNUNET_PQ_query_param_fixed_size(), GNUNET_SYSERR, namecache_postgres_expire_blocks(), plugin, and res.

Referenced by libgnunet_plugin_namecache_postgres_init().

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

◆ namecache_postgres_lookup_block()

static int namecache_postgres_lookup_block ( void *  cls,
const struct GNUNET_HashCode query,
GNUNET_NAMECACHE_BlockCallback  iter,
void *  iter_cls 
)
static

Get the block for a particular zone and label in the datastore.

Will return at most one result to the iterator.

Parameters
clsclosure (internal context for the plugin)
queryhash of public key derived from the zone and the label
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 228 of file plugin_namecache_postgres.c.

232 {
233  struct Plugin *plugin = cls;
234  size_t bsize;
235  struct GNUNET_GNSRECORD_Block *block;
236  struct GNUNET_PQ_QueryParam params[] = {
239  };
240  struct GNUNET_PQ_ResultSpec rs[] = {
242  (void **) &block,
243  &bsize),
245  };
247 
249  "lookup_block",
250  params,
251  rs);
252  if (0 > res)
253  {
255  "Failing lookup block in namecache (postgres error)\n");
256  return GNUNET_SYSERR;
257  }
259  {
260  /* no result */
262  "Ending iteration (no more results)\n");
263  return GNUNET_NO;
264  }
265  if ((bsize < sizeof(*block)))
266  {
267  GNUNET_break (0);
269  "Failing lookup (corrupt block)\n");
271  return GNUNET_SYSERR;
272  }
273  iter (iter_cls,
274  block);
276  return GNUNET_OK;
277 }
static unsigned int bsize
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
The transaction succeeded, but yielded zero results.
Definition: gnunet_db_lib.h:54
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_prepared_singleton_select(struct GNUNET_PQ_Context *db, const char *statement_name, const struct GNUNET_PQ_QueryParam *params, struct GNUNET_PQ_ResultSpec *rs)
Execute a named prepared statement that is a SELECT statement which must return a single result in co...
Definition: pq_eval.c:258
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:117
#define GNUNET_PQ_result_spec_end
End of result parameter specification.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
#define LOG(kind,...)
Description of a DB result cell.

References bsize, Plugin::dbh, GNUNET_break, GNUNET_DB_STATUS_SUCCESS_NO_RESULTS, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_NO, GNUNET_OK, GNUNET_PQ_cleanup_result(), GNUNET_PQ_eval_prepared_singleton_select(), GNUNET_PQ_query_param_auto_from_type, GNUNET_PQ_query_param_end, GNUNET_PQ_result_spec_end, GNUNET_PQ_result_spec_variable_size(), GNUNET_SYSERR, LOG, plugin, and res.

Referenced by libgnunet_plugin_namecache_postgres_init().

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 287 of file plugin_namecache_postgres.c.

288 {
290  plugin->dbh = NULL;
291 }
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:508

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

Referenced by libgnunet_plugin_namecache_postgres_done(), and libgnunet_plugin_namecache_postgres_init().

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

◆ libgnunet_plugin_namecache_postgres_init()

void* libgnunet_plugin_namecache_postgres_init ( void *  cls)

Entry point for the plugin.

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

Definition at line 301 of file plugin_namecache_postgres.c.

302 {
303  static struct Plugin plugin;
304  const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
306 
307  if (NULL != plugin.cfg)
308  return NULL; /* can only initialize once! */
309  memset (&plugin, 0, sizeof(struct Plugin));
310  plugin.cfg = cfg;
311  if (GNUNET_OK != database_setup (&plugin))
312  {
314  return NULL;
315  }
317  api->cls = &plugin;
321  "Postgres namecache plugin running\n");
322  return api;
323 }
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 void database_shutdown(struct Plugin *plugin)
Shutdown database connection and associate data structures.
static int namecache_postgres_lookup_block(void *cls, const struct GNUNET_HashCode *query, GNUNET_NAMECACHE_BlockCallback iter, void *iter_cls)
Get the block for a particular zone and label in the datastore.
static int namecache_postgres_cache_block(void *cls, const struct GNUNET_GNSRECORD_Block *block)
Cache a block in the datastore.
static int database_setup(struct Plugin *plugin)
Initialize the database connections and associated data structures (create tables and indices as need...
struct returned by the initialization function of the plugin
int(* lookup_block)(void *cls, const struct GNUNET_HashCode *query, GNUNET_NAMECACHE_BlockCallback iter, void *iter_cls)
Get the block for a particular zone and label in the datastore.
int(* cache_block)(void *cls, const struct GNUNET_GNSRECORD_Block *block)
Cache a block in the datastore.
void * cls
Closure to pass to all plugin functions.

References GNUNET_NAMECACHE_PluginFunctions::cache_block, cfg, Plugin::cfg, GNUNET_NAMECACHE_PluginFunctions::cls, database_setup(), database_shutdown(), GNUNET_ERROR_TYPE_INFO, GNUNET_new, GNUNET_OK, LOG, GNUNET_NAMECACHE_PluginFunctions::lookup_block, namecache_postgres_cache_block(), namecache_postgres_lookup_block(), and plugin.

Here is the call graph for this function:

◆ libgnunet_plugin_namecache_postgres_done()

void* libgnunet_plugin_namecache_postgres_done ( void *  cls)

Exit point from the plugin.

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

Definition at line 333 of file plugin_namecache_postgres.c.

334 {
336  struct Plugin *plugin = api->cls;
337 
339  plugin->cfg = NULL;
340  GNUNET_free (api);
342  "Postgres namecache plugin is finished\n");
343  return NULL;
344 }
#define GNUNET_free(ptr)
Wrapper around free.
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_NAMECACHE_PluginFunctions::cls, database_shutdown(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, LOG, and plugin.

Here is the call graph for this function: