GNUnet 0.28.0-dev.2-18-g144d0c5be
 
Loading...
Searching...
No Matches
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"
29#include "gnunet_pq_lib.h"
30
31
32#define LOG(kind, ...) GNUNET_log_from (kind, "namecache-postgres", __VA_ARGS__)
33
34
38struct Plugin
39{
40 const struct GNUNET_CONFIGURATION_Handle *cfg;
41
45 struct GNUNET_PQ_Context *dbh;
46
50 bool ready;
51};
52
53
61static void
62reconnect_setup (void *cls,
63 struct GNUNET_PQ_Context *pq)
64{
65 struct Plugin *plugin = cls;
67 GNUNET_PQ_make_prepare ("cache_block",
68 "INSERT INTO namecache.ns096blocks"
69 " (query, block, expiration_time)"
70 " VALUES"
71 " ($1, $2, $3)"),
72 GNUNET_PQ_make_prepare ("expire_blocks",
73 "DELETE FROM namecache.ns096blocks"
74 " WHERE expiration_time<$1"),
75 GNUNET_PQ_make_prepare ("delete_block",
76 "DELETE FROM namecache.ns096blocks"
77 " WHERE query=$1 AND expiration_time<=$2"),
78 GNUNET_PQ_make_prepare ("lookup_block",
79 "SELECT block"
80 " FROM namecache.ns096blocks"
81 " WHERE query=$1"
82 " ORDER BY expiration_time DESC LIMIT 1"),
84 };
85
86 if (GNUNET_SYSERR ==
88 {
89 plugin->ready = false;
90 return;
91 }
92 if (GNUNET_OK !=
94 "namecache-"))
95 {
96 plugin->ready = false;
97 return;
98 }
99 if (GNUNET_OK !=
101 ps))
102 {
103 plugin->ready = false;
104 return;
105 }
106 plugin->ready = true;
107}
108
109
120{
121 plugin->dbh = GNUNET_PQ_init (plugin->cfg,
122 "namecache-postgres",
124 plugin);
125 if (NULL == plugin->dbh)
126 return GNUNET_SYSERR;
127 if (! plugin->ready)
128 return GNUNET_NO;
129 return GNUNET_OK;
130}
131
132
138static void
153
154
162static void
164 const struct GNUNET_HashCode *query,
165 struct GNUNET_TIME_Absolute expiration_time)
166{
167 struct GNUNET_PQ_QueryParam params[] = {
169 GNUNET_PQ_query_param_absolute_time (&expiration_time),
171 };
173
175 "delete_block",
176 params);
178}
179
180
190 const struct GNUNET_GNSRECORD_Block *block)
191{
192 struct Plugin *plugin = cls;
193 struct GNUNET_HashCode query;
194 size_t block_size = GNUNET_GNSRECORD_block_get_size (block);
196 );
198
201 &query);
202 if (block_size > 64 * 65536)
203 {
204 GNUNET_break (0);
205 return GNUNET_SYSERR;
206 }
207 {
208 struct GNUNET_PQ_QueryParam params[] = {
210 GNUNET_PQ_query_param_fixed_size (block, block_size),
213 };
215 &query,
216 exp);
217
219 "cache_block",
220 params);
221 }
222 if (0 > res)
223 return GNUNET_SYSERR;
224 return GNUNET_OK;
225}
226
227
240 const struct GNUNET_HashCode *query,
242 void *iter_cls)
243{
244 struct Plugin *plugin = cls;
245 size_t bsize;
246 struct GNUNET_GNSRECORD_Block *block;
247 struct GNUNET_PQ_QueryParam params[] = {
250 };
251 struct GNUNET_PQ_ResultSpec rs[] = {
253 (void **) &block,
254 &bsize),
256 };
258
260 "lookup_block",
261 params,
262 rs);
263 if (0 > res)
264 {
266 "Failing lookup block in namecache (postgres error)\n");
267 return GNUNET_SYSERR;
268 }
270 {
271 /* no result */
273 "Ending iteration (no more results)\n");
274 return GNUNET_NO;
275 }
276 if ((bsize < sizeof(*block)))
277 {
278 GNUNET_break (0);
280 "Failing lookup (corrupt block)\n");
282 return GNUNET_SYSERR;
283 }
284 iter (iter_cls,
285 block);
287 return GNUNET_OK;
288}
289
290
297static void
299{
301 plugin->dbh = NULL;
302}
303
304
305void *
307
314void *
316{
317 static struct Plugin plugin;
318 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
320
321 if (NULL != plugin.cfg)
322 return NULL; /* can only initialize once! */
323 memset (&plugin,
324 0,
325 sizeof(struct Plugin));
326 plugin.cfg = cfg;
327 if (GNUNET_OK !=
329 {
331 return NULL;
332 }
334 api->cls = &plugin;
338 "Postgres namecache plugin running\n");
339 return api;
340}
341
342
343void *
345
352void *
354{
356 struct Plugin *plugin = api->cls;
357
359 plugin->cfg = NULL;
362 "Postgres namecache plugin is finished\n");
363 return NULL;
364}
365
366
367/* end of plugin_namecache_postgres.c */
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition gnunet-arm.c:108
static struct GNUNET_TESTING_PluginFunctions * plugin
Plugin to dynamically load a test case.
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.
@ GNUNET_DB_STATUS_HARD_ERROR
A hard error occurred, retrying will not help.
@ GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
The transaction succeeded, but yielded zero results.
API that can be used to manipulate GNS record data.
Plugin API for the namecache database backend.
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.
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.
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:73
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:678
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_Context * GNUNET_PQ_init(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, GNUNET_PQ_ReconnectCallback rc, void *rc_cls)
Connect to a postgres database using the configuration option "CONFIG" in section.
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:142
#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
enum GNUNET_GenericReturnValue GNUNET_PQ_load_versioning(struct GNUNET_PQ_Context *db)
Setup database versioning.
Definition pq_connect.c:602
#define GNUNET_PQ_result_spec_end
End of result parameter specification.
enum GNUNET_GenericReturnValue GNUNET_PQ_run_sql(struct GNUNET_PQ_Context *db, const char *load_suffix)
Within the db context, run all the SQL files in the load path where the name starts with the load_suf...
Definition pq_connect.c:398
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,...)
static void reconnect_setup(void *cls, struct GNUNET_PQ_Context *pq)
Function called whenever we reconnect to the DB.
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.
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
bool ready
Set to true if the DB is ready for action.
struct GNUNET_PQ_Context * dbh
Native Postgres database handle.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.