GNUnet 0.21.1
plugin_namecache_postgres.c
Go to the documentation of this file.
1/*
2 * This file is part of GNUnet
3 * Copyright (C) 2009-2013, 2016, 2017, 2022 GNUnet e.V.
4 *
5 * GNUnet is free software: you can redistribute it and/or modify it
6 * under the terms of the GNU Affero General Public License as published
7 * by the Free Software Foundation, either version 3 of the License,
8 * or (at your option) any later version.
9 *
10 * GNUnet is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
26#include "platform.h"
30#include "gnunet_pq_lib.h"
31
32
33#define LOG(kind, ...) GNUNET_log_from (kind, "namecache-postgres", __VA_ARGS__)
34
35
39struct Plugin
40{
41 const struct GNUNET_CONFIGURATION_Handle *cfg;
42
46 struct GNUNET_PQ_Context *dbh;
47};
48
49
60{
62 GNUNET_PQ_make_prepare ("cache_block",
63 "INSERT INTO namecache.ns096blocks"
64 " (query, block, expiration_time)"
65 " VALUES"
66 " ($1, $2, $3)"),
67 GNUNET_PQ_make_prepare ("expire_blocks",
68 "DELETE FROM namecache.ns096blocks"
69 " WHERE expiration_time<$1"),
70 GNUNET_PQ_make_prepare ("delete_block",
71 "DELETE FROM namecache.ns096blocks"
72 " WHERE query=$1 AND expiration_time<=$2"),
73 GNUNET_PQ_make_prepare ("lookup_block",
74 "SELECT block"
75 " FROM namecache.ns096blocks"
76 " WHERE query=$1"
77 " ORDER BY expiration_time DESC LIMIT 1"),
79 };
80
82 "namecache-postgres",
83 "namecache-",
84 NULL,
85 ps);
86 if (NULL == plugin->dbh)
87 return GNUNET_SYSERR;
88 return GNUNET_OK;
89}
90
91
97static void
99{
101 struct GNUNET_PQ_QueryParam params[] = {
104 };
106
108 "expire_blocks",
109 params);
111}
112
113
121static void
123 const struct GNUNET_HashCode *query,
124 struct GNUNET_TIME_Absolute expiration_time)
125{
126 struct GNUNET_PQ_QueryParam params[] = {
128 GNUNET_PQ_query_param_absolute_time (&expiration_time),
130 };
132
134 "delete_block",
135 params);
137}
138
139
149 const struct GNUNET_GNSRECORD_Block *block)
150{
151 struct Plugin *plugin = cls;
152 struct GNUNET_HashCode query;
153 size_t block_size = GNUNET_GNSRECORD_block_get_size (block);
154 struct GNUNET_TIME_Absolute exp;
156 struct GNUNET_PQ_QueryParam params[] = {
158 GNUNET_PQ_query_param_fixed_size (block, block_size),
161 };
163
166 &query);
167 if (block_size > 64 * 65536)
168 {
169 GNUNET_break (0);
170 return GNUNET_SYSERR;
171 }
173 &query,
174 exp);
175
177 "cache_block",
178 params);
179 if (0 > res)
180 return GNUNET_SYSERR;
181 return GNUNET_OK;
182}
183
184
197 const struct GNUNET_HashCode *query,
199 void *iter_cls)
200{
201 struct Plugin *plugin = cls;
202 size_t bsize;
203 struct GNUNET_GNSRECORD_Block *block;
204 struct GNUNET_PQ_QueryParam params[] = {
207 };
208 struct GNUNET_PQ_ResultSpec rs[] = {
210 (void **) &block,
211 &bsize),
213 };
215
217 "lookup_block",
218 params,
219 rs);
220 if (0 > res)
221 {
223 "Failing lookup block in namecache (postgres error)\n");
224 return GNUNET_SYSERR;
225 }
227 {
228 /* no result */
230 "Ending iteration (no more results)\n");
231 return GNUNET_NO;
232 }
233 if ((bsize < sizeof(*block)))
234 {
235 GNUNET_break (0);
237 "Failing lookup (corrupt block)\n");
239 return GNUNET_SYSERR;
240 }
241 iter (iter_cls,
242 block);
244 return GNUNET_OK;
245}
246
247
254static void
256{
258 plugin->dbh = NULL;
259}
260
261
268void *
270{
271 static struct Plugin plugin;
272 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
274
275 if (NULL != plugin.cfg)
276 return NULL; /* can only initialize once! */
277 memset (&plugin, 0, sizeof(struct Plugin));
278 plugin.cfg = cfg;
280 {
282 return NULL;
283 }
285 api->cls = &plugin;
289 "Postgres namecache plugin running\n");
290 return api;
291}
292
293
300void *
302{
304 struct Plugin *plugin = api->cls;
305
307 plugin->cfg = NULL;
310 "Postgres namecache plugin is finished\n");
311 return NULL;
312}
313
314
315/* end of plugin_namecache_postgres.c */
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:109
struct TestcasePlugin * plugin
The process handle to the testbed service.
static struct GNUNET_PEERSTORE_Handle * ps
Handle to the PEERSTORE service.
static char * res
Currently read line or NULL on EOF.
static unsigned int bsize
GNUNET_DB_QueryStatus
Status code returned from functions running database commands.
Definition: gnunet_db_lib.h:37
@ GNUNET_DB_STATUS_HARD_ERROR
A hard error occurred, retrying will not help.
Definition: gnunet_db_lib.h:41
@ GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
The transaction succeeded, but yielded zero results.
Definition: gnunet_db_lib.h:55
API that can be used to manipulate GNS record data.
Plugin API for the namecache database backend.
API that can be used to store naming information on a GNUnet node.
helper functions for Postgres DB interactions
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.
#define GNUNET_PQ_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.
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:619
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:199
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_absolute_time(const struct GNUNET_TIME_Absolute *x)
Generate query parameter for an absolute time value.
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:684
struct GNUNET_PQ_PreparedStatement GNUNET_PQ_make_prepare(const char *name, const char *sql)
Create a struct GNUNET_PQ_PreparedStatement.
Definition: pq_prepare.c:30
#define GNUNET_PQ_query_param_end
End of query parameter specification.
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:139
#define GNUNET_PQ_PREPARED_STATEMENT_END
Terminator for prepared statement list.
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:135
#define GNUNET_PQ_result_spec_end
End of result parameter specification.
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.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void(* GNUNET_NAMECACHE_BlockCallback)(void *cls, const struct GNUNET_GNSRECORD_Block *block)
Function called for matching blocks.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
static enum GNUNET_GenericReturnValue database_setup(struct Plugin *plugin)
Initialize the database connections and associated data structures (create tables and indices as need...
void * libgnunet_plugin_namecache_postgres_init(void *cls)
Entry point for the plugin.
static enum GNUNET_GenericReturnValue namecache_postgres_cache_block(void *cls, const struct GNUNET_GNSRECORD_Block *block)
Cache a block in the datastore.
static void database_shutdown(struct Plugin *plugin)
Shutdown database connection and associate data structures.
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.
#define LOG(kind,...)
void * libgnunet_plugin_namecache_postgres_done(void *cls)
Exit point from the plugin.
static enum GNUNET_GenericReturnValue 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.
void * cls
Closure for all of the callbacks.
A 512-bit hashcode.
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.
Handle to Postgres database.
Definition: pq.h:36
Information needed to prepare a list of SQL statements using GNUNET_PQ_prepare_statements().
Description of a DB query parameter.
Definition: gnunet_pq_lib.h:83
Description of a DB result cell.
void * cls
Closure for conv and cleaner.
Time for absolute times used by GNUnet, in microseconds.
Handle for a plugin.
Definition: block.c:38
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47
struct GNUNET_PQ_Context * dbh
Native Postgres database handle.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.