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.
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:404
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
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
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.