GNUnet 0.22.2
datacache.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2004-2010, 2015, 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 */
25#include "platform.h"
26#include "gnunet_util_lib.h"
30
31
32#define LOG(kind, ...) GNUNET_log_from (kind, "datacache", __VA_ARGS__)
33
34#define LOG_STRERROR_FILE(kind, op, fn) \
35 GNUNET_log_from_strerror_file (kind, "datacache", op, fn)
36
41{
46
51
56
60 char *section;
61
67
72
76 char *lib_name;
77
82
87
91 unsigned long long utilization;
92};
93
94
103static void
105 const struct GNUNET_HashCode *key,
106 size_t size)
107{
108 struct GNUNET_DATACACHE_Handle *h = cls;
109
111 "Content under key `%s' discarded\n",
112 GNUNET_h2s (key));
113 GNUNET_assert (h->utilization >= size);
114 h->utilization -= size;
117 "# bytes stored",
118 -(long long) size,
119 GNUNET_NO);
121 "# items stored",
122 -1,
123 GNUNET_NO);
124}
125
126
129 const char *section)
130{
131 unsigned int bf_size;
132 unsigned long long quota;
134 char *libname;
135 char *name;
136
137 if (GNUNET_OK !=
139 section,
140 "QUOTA",
141 &quota))
142 {
144 section,
145 "QUOTA");
146 return NULL;
147 }
148 if (GNUNET_OK !=
150 section,
151 "DATABASE",
152 &name))
153 {
155 section,
156 "DATABASE");
157 return NULL;
158 }
159 bf_size = quota / 32; /* 8 bit per entry, 1 bit per 32 kb in DB */
160
162
163 if (GNUNET_YES !=
165 section,
166 "DISABLE_BF"))
167 {
168 if (GNUNET_YES !=
170 section,
171 "DISABLE_BF_RC"))
172 {
173 ret->bloom_name = GNUNET_DISK_mktemp ("gnunet-datacachebloom");
174 }
175 if (NULL != ret->bloom_name)
176 {
178 ret->bloom_name,
179 quota / 1024, /* 8 bit per entry in DB, expect 1k entries */
180 5);
181 }
182 if (NULL == ret->filter)
183 {
184 ret->filter =
186 bf_size,
187 5); /* approx. 3% false positives at max use */
188 }
189 }
190 ret->stats = GNUNET_STATISTICS_create ("datacache",
191 cfg);
192 ret->section = GNUNET_strdup (section);
193 ret->env.cfg = cfg;
194 ret->env.delete_notify = &env_delete_notify;
195 ret->env.section = ret->section;
196 ret->env.cls = ret;
197 ret->env.delete_notify = &env_delete_notify;
198 ret->env.quota = quota;
200 "Loading `%s' datacache plugin\n",
201 name);
202 GNUNET_asprintf (&libname,
203 "libgnunet_plugin_datacache_%s",
204 name);
205 ret->short_name = name;
206 ret->lib_name = libname;
207 /* Load the plugin within GNUnet's default context */
209 libname,
210 &ret->env);
211 if (NULL == ret->api)
212 {
214 "Failed to load datacache plugin for `%s'\n",
215 name);
217 return NULL;
218 }
219 return ret;
220}
221
222
223void
225{
226 if (NULL != h->filter)
228 if (NULL != h->api)
229 GNUNET_break (NULL ==
230 GNUNET_PLUGIN_unload (h->lib_name,
231 h->api));
232 GNUNET_free (h->lib_name);
233 GNUNET_free (h->short_name);
234 GNUNET_free (h->section);
235 if (NULL != h->bloom_name)
236 {
237 if (0 != unlink (h->bloom_name))
239 "datacache",
240 "unlink",
241 h->bloom_name);
242 GNUNET_free (h->bloom_name);
243 }
245 GNUNET_free (h);
246}
247
248
251 uint32_t xor_distance,
252 const struct GNUNET_DATACACHE_Block *block)
253{
254 ssize_t used;
255
256 used = h->api->put (h->api->cls,
257 xor_distance,
258 block);
259 if (-1 == used)
260 {
261 GNUNET_break (0);
262 return GNUNET_SYSERR;
263 }
264 if (0 == used)
265 {
266 /* duplicate */
267 return GNUNET_NO;
268 }
270 "Stored data under key `%s' in cache\n",
271 GNUNET_h2s (&block->key));
272 if (NULL != h->filter)
274 &block->key);
276 "# bytes stored",
277 used,
278 GNUNET_NO);
280 "# items stored",
281 1,
282 GNUNET_NO);
283 while (h->utilization + used > h->env.quota)
285 h->api->del (h->api->cls));
286 h->utilization += used;
287 return GNUNET_OK;
288}
289
290
291unsigned int
293 const struct GNUNET_HashCode *key,
296 void *iter_cls)
297{
299 "# requests received",
300 1,
301 GNUNET_NO);
303 "Processing request for key `%s'\n",
304 GNUNET_h2s (key));
305 if ( (NULL != h->filter) &&
306 (GNUNET_OK !=
308 key)) )
309 {
311 "# requests filtered by bloom filter",
312 1,
313 GNUNET_NO);
315 "Bloomfilter filters request for key `%s'\n",
316 GNUNET_h2s (key));
317 return 0; /* can not be present */
318 }
319 return h->api->get (h->api->cls,
320 key,
321 type,
322 iter, iter_cls);
323}
324
325
326unsigned int
328 const struct GNUNET_HashCode *key,
330 unsigned int num_results,
332 void *iter_cls)
333{
335 "# proximity search requests received",
336 1,
337 GNUNET_NO);
339 "Processing proximity search at `%s'\n",
340 GNUNET_h2s (key));
341 return h->api->get_closest (h->api->cls,
342 key,
343 type,
344 num_results,
345 iter,
346 iter_cls);
347}
348
349
350/* end of datacache.c */
static void env_delete_notify(void *cls, const struct GNUNET_HashCode *key, size_t size)
Function called by plugins to notify the datacache about content deletions.
Definition: datacache.c:104
#define LOG(kind,...)
Definition: datacache.c:32
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:98
static int ret
Final status code.
Definition: gnunet-arm.c:93
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:108
struct GNUNET_HashCode key
The key used in the DHT.
static char * name
Name (label) of the records to list.
static uint32_t type
Type string converted to DNS type value.
static unsigned long long quota
How much space are we allowed to use?
API for database backends for the datacache.
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
API to create, modify and access statistics.
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
void GNUNET_CONTAINER_bloomfilter_add(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Add an element to the filter.
bool GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_load(const char *filename, size_t size, unsigned int k)
Load a Bloom filter from a file.
void GNUNET_CONTAINER_bloomfilter_remove(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Remove an element from the filter.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associated with a filter in memory, flush to drive if needed (do not free the space on...
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_size(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *size)
Get a configuration value that should be a size in bytes.
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".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
const struct GNUNET_OS_ProjectData * GNUNET_CONFIGURATION_get_project_data(const struct GNUNET_CONFIGURATION_Handle *cfg)
Return the project data associated with this configuration.
unsigned int GNUNET_DATACACHE_get(struct GNUNET_DATACACHE_Handle *h, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results for a particular key in the datacache.
Definition: datacache.c:292
enum GNUNET_GenericReturnValue GNUNET_DATACACHE_put(struct GNUNET_DATACACHE_Handle *h, uint32_t xor_distance, const struct GNUNET_DATACACHE_Block *block)
Store an item in the datacache.
Definition: datacache.c:250
struct GNUNET_DATACACHE_Handle * GNUNET_DATACACHE_create(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section)
Create a data cache.
Definition: datacache.c:128
enum GNUNET_GenericReturnValue(* GNUNET_DATACACHE_Iterator)(void *cls, const struct GNUNET_DATACACHE_Block *block)
An iterator over a set of items stored in the datacache.
void GNUNET_DATACACHE_destroy(struct GNUNET_DATACACHE_Handle *h)
Destroy a data cache (and free associated resources).
Definition: datacache.c:224
unsigned int GNUNET_DATACACHE_get_closest(struct GNUNET_DATACACHE_Handle *h, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, unsigned int num_results, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results that are "close" to a particular key in the datacache.
Definition: datacache.c:327
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
Definition: disk.c:418
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_log_from_strerror_file(level, component, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
#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.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_PLUGIN_load(const struct GNUNET_OS_ProjectData *pd, const char *library_name, void *arg)
Setup plugin (runs the "init" callback and returns whatever "init" returned).
Definition: plugin.c:221
void * GNUNET_PLUGIN_unload(const char *library_name, void *arg)
Unload plugin (runs the "done" callback and returns whatever "done" returned).
Definition: plugin.c:277
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
static unsigned int size
Size of the "table".
Definition: peer.c:68
Information about a block stored in the datacache.
struct GNUNET_HashCode key
Key of the block.
Internal state of the datacache library.
Definition: datacache.c:41
char * bloom_name
Name for the bloom filter file.
Definition: datacache.c:81
unsigned long long utilization
How much space is in use right now?
Definition: datacache.c:91
struct GNUNET_DATACACHE_PluginEnvironment env
Environment provided to our plugin.
Definition: datacache.c:86
char * section
Configuration section to use.
Definition: datacache.c:60
char * short_name
Short name for the plugin (e.g.
Definition: datacache.c:71
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: datacache.c:50
struct GNUNET_STATISTICS_Handle * stats
Opaque handle for the statistics service.
Definition: datacache.c:55
struct GNUNET_CONTAINER_BloomFilter * filter
Bloomfilter to quickly tell if we don't have the content.
Definition: datacache.c:45
char * lib_name
Name of the library (e.g.
Definition: datacache.c:76
struct GNUNET_DATACACHE_PluginFunctions * api
API of the transport as returned by the plugin's initialization function.
Definition: datacache.c:66
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
void * cls
Closure to use for callbacks.
struct returned by the initialization function of the plugin
A 512-bit hashcode.
Handle for the service.