GNUnet debian-0.24.3-23-g589b01d60
gnunet-service-messenger_message_store.c File Reference
#include "gnunet-service-messenger_message_store.h"
#include "gnunet-service-messenger_list_messages.h"
#include "gnunet_common.h"
#include "gnunet_network_lib.h"
#include "gnunet_scheduler_lib.h"
#include "gnunet_util_lib.h"
#include "messenger_api_message.h"
#include <stdint.h>
#include <string.h>
Include dependency graph for gnunet-service-messenger_message_store.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_MESSENGER_MessageEntryStorage
 
struct  GNUNET_MESSENGER_MessageLinkStorage
 
struct  GNUNET_MESSENGER_ClosureMessageSave
 
struct  GNUNET_MESSENGER_CleanupDiscourseMessages
 

Macros

#define load_message_store_attribute_failed(file, attribute, size)
 
#define save_message_store_attribute_failed(file, attribute)
 

Functions

void init_message_store (struct GNUNET_MESSENGER_MessageStore *store, const char *directory)
 Initializes a message store as fully empty using a specific directory. More...
 
static enum GNUNET_GenericReturnValue iterate_destroy_entries (void *cls, const struct GNUNET_HashCode *key, void *value)
 
static enum GNUNET_GenericReturnValue iterate_destroy_messages (void *cls, const struct GNUNET_HashCode *key, void *value)
 
static enum GNUNET_GenericReturnValue iterate_destroy_hashs (void *cls, const struct GNUNET_HashCode *key, void *value)
 
void clear_message_store (struct GNUNET_MESSENGER_MessageStore *store)
 Clears a message store, wipes its content and deallocates its memory. More...
 
void move_message_store (struct GNUNET_MESSENGER_MessageStore *store, const char *directory)
 Moves all storage from a message store from its current directory to a given directory. More...
 
static int load_message_store_attribute (const struct GNUNET_DISK_FileHandle *file, void *attribute, size_t attribute_len, uint64_t *size)
 
static void load_message_store_entries (struct GNUNET_MESSENGER_MessageStore *store, const char *filename)
 
static void load_message_store_links (struct GNUNET_MESSENGER_MessageStore *store, const char *filename)
 
static void load_message_store_epochs (struct GNUNET_MESSENGER_MessageStore *store, const char *filename)
 
void load_message_store (struct GNUNET_MESSENGER_MessageStore *store)
 Loads messages from its directory into a message store. More...
 
static enum GNUNET_GenericReturnValue iterate_save_epochs (void *cls, const struct GNUNET_HashCode *key, void *value)
 
static enum GNUNET_GenericReturnValue iterate_save_links (void *cls, const struct GNUNET_HashCode *key, void *value)
 
static enum GNUNET_GenericReturnValue iterate_save_entries (void *cls, const struct GNUNET_HashCode *key, void *value)
 
static enum GNUNET_GenericReturnValue iterate_save_messages (void *cls, const struct GNUNET_HashCode *key, void *value)
 
void save_message_store (struct GNUNET_MESSENGER_MessageStore *store)
 Saves messages from a message store into its directory. More...
 
enum GNUNET_GenericReturnValue contains_store_message (const struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
 Checks if a message matching a given hash is stored in a message store. More...
 
const struct GNUNET_MESSENGER_Messageget_store_message (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
 Returns the message from a message store matching a given hash. More...
 
const struct GNUNET_MESSENGER_MessageLinkget_store_message_link (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash, enum GNUNET_GenericReturnValue deleted_only)
 Returns the message link from a message store matching a given hash. More...
 
const struct GNUNET_HashCodeget_store_message_epoch (const struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
 Returns the epoch hash of a message from a message store matching a given hash. More...
 
static void add_link (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_Message *message)
 
static void put_store_message_epoch (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash, const struct GNUNET_HashCode *epoch)
 
static void task_save_messages (void *cls)
 
enum GNUNET_GenericReturnValue put_store_message (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash, struct GNUNET_MESSENGER_Message *message)
 Stores a message into the message store. More...
 
enum GNUNET_GenericReturnValue delete_store_message (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
 Deletes a message in the message store. More...
 
static enum GNUNET_GenericReturnValue iterate_flag_for_cleanup_discourse_message (void *cls, const struct GNUNET_HashCode *key, void *value)
 
void cleanup_store_discourse_messages_before (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_ShortHashCode *discourse, const struct GNUNET_TIME_Absolute timestamp)
 Cleans up and deletes all discourse messages existing in the message store memory before a certain timestamp. More...
 

Macro Definition Documentation

◆ load_message_store_attribute_failed

#define load_message_store_attribute_failed (   file,
  attribute,
  size 
)
Value:
load_message_store_attribute (file, &(attribute), sizeof(attribute), \
&(size))
static int load_message_store_attribute(const struct GNUNET_DISK_FileHandle *file, void *attribute, size_t attribute_len, uint64_t *size)
static unsigned int size
Size of the "table".
Definition: peer.c:68

Definition at line 207 of file gnunet-service-messenger_message_store.c.

◆ save_message_store_attribute_failed

#define save_message_store_attribute_failed (   file,
  attribute 
)
Value:
sizeof(attribute) != GNUNET_DISK_file_write (file, &(attribute), \
sizeof(attribute))
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:710

Definition at line 211 of file gnunet-service-messenger_message_store.c.

Function Documentation

◆ init_message_store()

void init_message_store ( struct GNUNET_MESSENGER_MessageStore store,
const char *  directory 
)

Initializes a message store as fully empty using a specific directory.

Parameters
[out]storeMessage store
[in]directoryPath to a directory

Definition at line 40 of file gnunet-service-messenger_message_store.c.

42{
43 GNUNET_assert (store);
44
45 store->directory = directory? GNUNET_strdup (directory) : NULL;
46
47 store->storage_messages = NULL;
48 store->writing_task = NULL;
49
55
57 store->write_links = GNUNET_NO;
58}
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
@ GNUNET_NO
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct GNUNET_CONTAINER_MultiHashMap * links
struct GNUNET_DISK_FileHandle * storage_messages
struct GNUNET_CONTAINER_MultiHashMap * messages
struct GNUNET_CONTAINER_MultiHashMap * entries
struct GNUNET_CONTAINER_MultiHashMap * epochs
struct GNUNET_CONTAINER_MultiHashMap * discourses

References GNUNET_MESSENGER_MessageStore::directory, GNUNET_MESSENGER_MessageStore::discourses, GNUNET_MESSENGER_MessageStore::entries, GNUNET_MESSENGER_MessageStore::epochs, GNUNET_assert, GNUNET_CONTAINER_multihashmap_create(), GNUNET_NO, GNUNET_strdup, GNUNET_MESSENGER_MessageStore::links, GNUNET_MESSENGER_MessageStore::messages, GNUNET_MESSENGER_MessageStore::rewrite_entries, GNUNET_MESSENGER_MessageStore::storage_messages, GNUNET_MESSENGER_MessageStore::write_links, and GNUNET_MESSENGER_MessageStore::writing_task.

Referenced by create_srv_room().

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

◆ iterate_destroy_entries()

static enum GNUNET_GenericReturnValue iterate_destroy_entries ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Definition at line 62 of file gnunet-service-messenger_message_store.c.

65{
67
69
70 entry = value;
71
72 GNUNET_free (entry);
73 return GNUNET_YES;
74}
static char * value
Value of the record to add/remove.
@ GNUNET_YES
#define GNUNET_free(ptr)
Wrapper around free.

References GNUNET_assert, GNUNET_free, GNUNET_YES, and value.

Referenced by clear_message_store().

Here is the caller graph for this function:

◆ iterate_destroy_messages()

static enum GNUNET_GenericReturnValue iterate_destroy_messages ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Definition at line 78 of file gnunet-service-messenger_message_store.c.

81{
82 struct GNUNET_MESSENGER_Message *message;
83
85
86 message = value;
87
88 destroy_message (message);
89 return GNUNET_YES;
90}
void destroy_message(struct GNUNET_MESSENGER_Message *message)
Destroys a message and frees its memory fully.

References destroy_message(), GNUNET_assert, GNUNET_YES, and value.

Referenced by clear_message_store().

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

◆ iterate_destroy_hashs()

static enum GNUNET_GenericReturnValue iterate_destroy_hashs ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Definition at line 94 of file gnunet-service-messenger_message_store.c.

97{
98 struct GNUNET_HashCode *hash;
99
101
102 hash = value;
103
104 GNUNET_free (hash);
105 return GNUNET_YES;
106}
A 512-bit hashcode.

References GNUNET_assert, GNUNET_free, GNUNET_YES, and value.

Referenced by clear_message_store().

Here is the caller graph for this function:

◆ clear_message_store()

void clear_message_store ( struct GNUNET_MESSENGER_MessageStore store)

Clears a message store, wipes its content and deallocates its memory.

Parameters
[in,out]storeMessage store

Definition at line 110 of file gnunet-service-messenger_message_store.c.

111{
112 GNUNET_assert (store);
113
114 if (store->storage_messages)
115 {
117 store->storage_messages = NULL;
118 }
119
120 if (store->writing_task)
121 {
123 store->writing_task = NULL;
124 }
125
131 NULL);
135 NULL);
136
142
143 if (store->directory)
144 {
145 GNUNET_free (store->directory);
146 store->directory = NULL;
147 }
148}
static enum GNUNET_GenericReturnValue iterate_destroy_hashs(void *cls, const struct GNUNET_HashCode *key, void *value)
static enum GNUNET_GenericReturnValue iterate_destroy_entries(void *cls, const struct GNUNET_HashCode *key, void *value)
static enum GNUNET_GenericReturnValue iterate_destroy_messages(void *cls, const struct GNUNET_HashCode *key, void *value)
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1332
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:980

References GNUNET_MESSENGER_MessageStore::directory, GNUNET_MESSENGER_MessageStore::discourses, GNUNET_MESSENGER_MessageStore::entries, GNUNET_MESSENGER_MessageStore::epochs, GNUNET_assert, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_DISK_file_close(), GNUNET_free, GNUNET_SCHEDULER_cancel(), iterate_destroy_entries(), iterate_destroy_hashs(), iterate_destroy_messages(), GNUNET_MESSENGER_MessageStore::links, GNUNET_MESSENGER_MessageStore::messages, GNUNET_MESSENGER_MessageStore::storage_messages, and GNUNET_MESSENGER_MessageStore::writing_task.

Referenced by destroy_srv_room().

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

◆ move_message_store()

void move_message_store ( struct GNUNET_MESSENGER_MessageStore store,
const char *  directory 
)

Moves all storage from a message store from its current directory to a given directory.

Parameters
[in,out]storeMessage store
[in]directoryPath to a directory

Definition at line 152 of file gnunet-service-messenger_message_store.c.

154{
155 GNUNET_assert ((store) && (directory));
156
157 if (store->directory)
158 {
159 if (0 == strcmp (store->directory, directory))
160 return;
161
163 {
165 "Moving message store failed because directory exists already! (%s)\n",
166 directory);
167 return;
168 }
169
170 if (0 != rename (store->directory, directory))
171 {
173 "Moving message store failed! (%s -> %s)\n",
174 store->directory, directory);
175 return;
176 }
177
178 GNUNET_free (store->directory);
179 }
180
181 store->directory = GNUNET_strdup (directory);
182}
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition: disk.c:454
#define GNUNET_log(kind,...)
@ GNUNET_ERROR_TYPE_ERROR

References GNUNET_MESSENGER_MessageStore::directory, GNUNET_assert, GNUNET_DISK_directory_test(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_NO, GNUNET_strdup, and GNUNET_YES.

Referenced by load_srv_room(), and save_srv_room().

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

◆ load_message_store_attribute()

static int load_message_store_attribute ( const struct GNUNET_DISK_FileHandle file,
void *  attribute,
size_t  attribute_len,
uint64_t *  size 
)
static

Definition at line 192 of file gnunet-service-messenger_message_store.c.

196{
197 ssize_t result;
198
199 result = GNUNET_DISK_file_read (file, attribute, attribute_len);
200 if (GNUNET_SYSERR != result)
201 *size -= result;
202
203 return attribute_len != result;
204}
static int result
Global testing status.
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:673
@ GNUNET_SYSERR

References GNUNET_DISK_file_read(), GNUNET_SYSERR, result, and size.

Here is the call graph for this function:

◆ load_message_store_entries()

static void load_message_store_entries ( struct GNUNET_MESSENGER_MessageStore store,
const char *  filename 
)
static

Definition at line 216 of file gnunet-service-messenger_message_store.c.

218{
219 enum GNUNET_DISK_AccessPermissions permission;
220 struct GNUNET_DISK_FileHandle *entries;
222 struct GNUNET_MESSENGER_MessageEntry *entry;
223 uint64_t entry_size, size;
224
227 return;
228
229 entry_size = sizeof(storage.hash) + sizeof(storage.entry.offset) + sizeof(
230 storage.entry.length);
231
232 if (size < entry_size)
233 return;
234
235 permission = (GNUNET_DISK_PERM_USER_READ);
237 permission);
238
239 if (! entries)
240 return;
241
242 memset (&storage, 0, sizeof(storage));
243 entry = NULL;
244
245 while (size >= entry_size)
246 {
247 if ((load_message_store_attribute_failed (entries, storage.hash, size)) ||
248 (load_message_store_attribute_failed (entries, storage.entry.offset,
249 size)) ||
250 (load_message_store_attribute_failed (entries, storage.entry.length,
251 size)))
252 {
253 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Loading message entry failed!\n");
254 break;
255 }
256
258
259 if (! entry)
260 break;
261
262 GNUNET_memcpy (entry, &(storage.entry), sizeof(*entry));
263
265 store->entries, &(storage.hash))) ||
267 store->entries, &(storage.hash), entry,
269 {
271 "Loading message entry twice: %s\n",
272 GNUNET_h2s (&(storage.hash)));
274 break;
275 }
276
278 "Loading message entry with hash: %s\n",
279 GNUNET_h2s (&(storage.hash)));
280
281 entry = NULL;
282 }
283
284 if (entry)
285 GNUNET_free (entry);
286
287 GNUNET_DISK_file_close (entries);
288}
static char * filename
#define load_message_store_attribute_failed(file, attribute, size)
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1258
enum GNUNET_GenericReturnValue GNUNET_DISK_file_size(const char *filename, uint64_t *size, int include_symbolic_links, int single_file_mode)
Get the size of the file (or directory) of the given file (in bytes).
Definition: disk.c:235
GNUNET_DISK_AccessPermissions
File access permissions, UNIX-style.
@ GNUNET_DISK_OPEN_READ
Open the file for reading.
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL).
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Handle used to access files (and pipes).

References GNUNET_MESSENGER_MessageStore::entries, GNUNET_MESSENGER_MessageEntryStorage::entry, filename, GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST, GNUNET_DISK_file_close(), GNUNET_DISK_file_open(), GNUNET_DISK_file_size(), GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_USER_READ, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_memcpy, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_YES, GNUNET_MESSENGER_MessageEntryStorage::hash, GNUNET_MESSENGER_MessageEntry::length, load_message_store_attribute_failed, GNUNET_MESSENGER_MessageEntry::offset, GNUNET_MESSENGER_MessageStore::rewrite_entries, and size.

Referenced by load_message_store().

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

◆ load_message_store_links()

static void load_message_store_links ( struct GNUNET_MESSENGER_MessageStore store,
const char *  filename 
)
static

Definition at line 298 of file gnunet-service-messenger_message_store.c.

300{
301 enum GNUNET_DISK_AccessPermissions permission;
304 struct GNUNET_MESSENGER_MessageLink *link;
305 uint64_t link_size, size;
306
309 return;
310
311 link_size = sizeof(storage.hash) + sizeof(storage.link.multiple) + sizeof(
312 storage.link.first);
313
314 if (size < link_size)
315 return;
316
317 permission = (GNUNET_DISK_PERM_USER_READ);
318
320 permission);
321
322 if (! links)
323 return;
324
325 memset (&storage, 0, sizeof(storage));
326 link = NULL;
327
328 while (size >= link_size)
329 {
330 if ((load_message_store_attribute_failed (links, storage.hash, size)) ||
332 storage.link.multiple, size)) ||
333 (load_message_store_attribute_failed (links, storage.link.first, size))
334 ||
335 ((GNUNET_YES == storage.link.multiple) &&
336 (load_message_store_attribute_failed (links, storage.link.second, size)
337 )))
338 break;
339
341
342 if (! link)
343 break;
344
345 GNUNET_memcpy (link, &(storage.link), sizeof(*link));
346
348 store->links, &(storage.hash))) ||
350 store->links, &(storage.hash), link,
352 break;
353
354 link = NULL;
355 }
356
357 if (link)
358 GNUNET_free (link);
359
361}
static struct GNUNET_CONTAINER_MultiPeerMap * links
Map from PIDs to struct VirtualLink entries describing links CORE knows to exist.

References filename, GNUNET_MESSENGER_MessageLink::first, GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST, GNUNET_DISK_file_close(), GNUNET_DISK_file_open(), GNUNET_DISK_file_size(), GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_USER_READ, GNUNET_free, GNUNET_memcpy, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_YES, GNUNET_MESSENGER_MessageLinkStorage::hash, GNUNET_MESSENGER_MessageLinkStorage::link, GNUNET_MESSENGER_MessageStore::links, links, load_message_store_attribute_failed, GNUNET_MESSENGER_MessageLink::multiple, GNUNET_MESSENGER_MessageLink::second, and size.

Referenced by load_message_store().

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

◆ load_message_store_epochs()

static void load_message_store_epochs ( struct GNUNET_MESSENGER_MessageStore store,
const char *  filename 
)
static

Definition at line 365 of file gnunet-service-messenger_message_store.c.

367{
368 enum GNUNET_DISK_AccessPermissions permission;
370 struct GNUNET_HashCode storage[2];
371 struct GNUNET_HashCode *epoch;
372 uint64_t epoch_size, size;
373
376 return;
377
378 epoch_size = sizeof(storage[0]) + sizeof(storage[1]);
379
380 if (size < epoch_size)
381 return;
382
383 permission = (GNUNET_DISK_PERM_USER_READ);
384
386 permission);
387
388 if (! epochs)
389 return;
390
391 epoch = NULL;
392
393 while (size >= epoch_size)
394 {
395 if ((load_message_store_attribute_failed (epochs, storage[0], size)) ||
397 break;
398
399 epoch = GNUNET_new (struct GNUNET_HashCode);
400
401 if (! epoch)
402 break;
403
404 GNUNET_memcpy (epoch, &(storage[1]), sizeof(*epoch));
405
407 store->epochs, &(storage[0]))) ||
409 store->epochs, &(storage[0]), epoch,
411 break;
412
413 epoch = NULL;
414 }
415
416 if (epoch)
417 GNUNET_free (epoch);
418
420}
static unsigned int epochs
-e option.

References epochs, GNUNET_MESSENGER_MessageStore::epochs, filename, GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST, GNUNET_DISK_file_close(), GNUNET_DISK_file_open(), GNUNET_DISK_file_size(), GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_USER_READ, GNUNET_free, GNUNET_memcpy, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_YES, load_message_store_attribute_failed, and size.

Referenced by load_message_store().

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

◆ load_message_store()

void load_message_store ( struct GNUNET_MESSENGER_MessageStore store)

Loads messages from its directory into a message store.

Parameters
[out]storeMessage store

Definition at line 424 of file gnunet-service-messenger_message_store.c.

425{
426 enum GNUNET_DISK_AccessPermissions permission;
427 char *filename;
428
429 GNUNET_assert (store);
430
431 if (! store->directory)
432 return;
433
435
436 if (store->storage_messages)
438
440 "%s%s", store->directory, "messages.store");
441
445 permission);
446 else
447 store->storage_messages = NULL;
448
450
451 if (! store->storage_messages)
452 return;
453
455 "%s%s", store->directory, "entries.store");
456
459
461
463 "%s%s", store->directory, "links.store");
464
467
469 "%s%s", store->directory, "epochs.store");
470
473
475}
static void load_message_store_entries(struct GNUNET_MESSENGER_MessageStore *store, const char *filename)
static void load_message_store_links(struct GNUNET_MESSENGER_MessageStore *store, const char *filename)
static void load_message_store_epochs(struct GNUNET_MESSENGER_MessageStore *store, const char *filename)
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition: disk.c:533
@ GNUNET_DISK_OPEN_READWRITE
Open the file for both reading and writing.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.

References GNUNET_MESSENGER_MessageStore::directory, filename, GNUNET_asprintf(), GNUNET_assert, GNUNET_DISK_file_close(), GNUNET_DISK_file_open(), GNUNET_DISK_file_test(), GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_READ, GNUNET_DISK_PERM_USER_WRITE, GNUNET_free, GNUNET_YES, load_message_store_entries(), load_message_store_epochs(), load_message_store_links(), and GNUNET_MESSENGER_MessageStore::storage_messages.

Referenced by load_srv_room().

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

◆ iterate_save_epochs()

static enum GNUNET_GenericReturnValue iterate_save_epochs ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Definition at line 487 of file gnunet-service-messenger_message_store.c.

490{
492 struct GNUNET_HashCode *epoch;
493
494 GNUNET_assert ((cls) && (key) && (value));
495
496 save = cls;
497 epoch = value;
498
499 if ((save_message_store_attribute_failed (save->storage, (*key))) ||
500 (save_message_store_attribute_failed (save->storage, (*epoch))))
501 return GNUNET_NO;
502
503 return GNUNET_YES;
504}
struct GNUNET_HashCode key
The key used in the DHT.
#define save_message_store_attribute_failed(file, attribute)
static void save()
Write persistent statistics to disk.

References GNUNET_assert, GNUNET_NO, GNUNET_YES, key, save(), save_message_store_attribute_failed, and value.

Referenced by save_message_store().

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

◆ iterate_save_links()

static enum GNUNET_GenericReturnValue iterate_save_links ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Definition at line 508 of file gnunet-service-messenger_message_store.c.

511{
513 struct GNUNET_MESSENGER_MessageLink *link;
514
515 GNUNET_assert ((cls) && (key) && (value));
516
517 save = cls;
518 link = value;
519
520 if ((save_message_store_attribute_failed (save->storage, (*key))) ||
523 return GNUNET_NO;
524
525 if ((GNUNET_YES == link->multiple) &&
527 return GNUNET_NO;
528
529 return GNUNET_YES;
530}

References GNUNET_MESSENGER_MessageLink::first, GNUNET_assert, GNUNET_NO, GNUNET_YES, key, GNUNET_MESSENGER_MessageLink::multiple, save(), save_message_store_attribute_failed, GNUNET_MESSENGER_MessageLink::second, and value.

Referenced by save_message_store().

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

◆ iterate_save_entries()

static enum GNUNET_GenericReturnValue iterate_save_entries ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Definition at line 534 of file gnunet-service-messenger_message_store.c.

537{
539 struct GNUNET_MESSENGER_MessageEntry *entry;
540
541 GNUNET_assert ((cls) && (key) && (value));
542
543 save = cls;
544 entry = value;
545
546 if ((save_message_store_attribute_failed (save->storage, (*key))) ||
547 (save_message_store_attribute_failed (save->storage, entry->offset)) ||
549 return GNUNET_NO;
550
551 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing message entry with hash: %s\n",
552 GNUNET_h2s (key));
553
554 return GNUNET_YES;
555}

References GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_NO, GNUNET_YES, key, GNUNET_MESSENGER_MessageEntry::length, GNUNET_MESSENGER_MessageEntry::offset, save(), save_message_store_attribute_failed, and value.

Referenced by save_message_store().

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

◆ iterate_save_messages()

static enum GNUNET_GenericReturnValue iterate_save_messages ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Definition at line 559 of file gnunet-service-messenger_message_store.c.

562{
565 struct GNUNET_MESSENGER_Message *message;
566
567 GNUNET_assert ((cls) && (key) && (value));
568
569 save = cls;
570
572 save->store->entries, key))
573 {
575 "Skipping storage of message: %s\n", GNUNET_h2s (key));
576 return GNUNET_YES;
577 }
578
579 message = value;
580
581 GNUNET_memcpy (&(storage.hash), key, sizeof(storage.hash));
582
583 storage.entry.length = get_message_size (message, GNUNET_YES);
584 storage.entry.offset = GNUNET_DISK_file_seek (
585 save->store->storage_messages, 0, GNUNET_DISK_SEEK_END);
586
587 if ((GNUNET_SYSERR == storage.entry.offset) ||
588 (save_message_store_attribute_failed (save->storage, storage.hash)) ||
590 storage.entry.offset)) ||
592 storage.entry.length)))
593 {
595 "Storing entry of message failed: %s\n", GNUNET_h2s (key));
596 return GNUNET_NO;
597 }
598
599 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing message with hash: %s\n",
600 GNUNET_h2s (&(storage.hash)));
601
602 {
603 char *buffer;
604 buffer = GNUNET_malloc (storage.entry.length);
605
606 if (! buffer)
607 return GNUNET_NO;
608
609 encode_message (message, storage.entry.length, buffer, GNUNET_YES);
610
611 GNUNET_DISK_file_write (save->store->storage_messages, buffer,
612 storage.entry.length);
613
614 GNUNET_free (buffer);
615 }
616
617 {
618 struct GNUNET_MESSENGER_MessageEntry *entry;
620
621 if (! entry)
622 return GNUNET_NO;
623
624 GNUNET_memcpy (entry, &(storage.entry), sizeof(*entry));
625
627 save->store->entries, &(storage.hash), entry,
629 {
631 "Message entry might get stored twice: %s\n",
632 GNUNET_h2s (&(storage.hash)));
633 GNUNET_free (entry);
634 return GNUNET_NO;
635 }
636 }
637
638 return GNUNET_YES;
639}
off_t GNUNET_DISK_file_seek(const struct GNUNET_DISK_FileHandle *h, off_t offset, enum GNUNET_DISK_Seek whence)
Move the read/write pointer in a file.
Definition: disk.c:219
@ GNUNET_DISK_SEEK_END
Seek an absolute position from the end of the file.
#define GNUNET_malloc(size)
Wrapper around malloc.
void encode_message(const struct GNUNET_MESSENGER_Message *message, uint16_t length, char *buffer, enum GNUNET_GenericReturnValue include_header)
Encodes a given message into a buffer of a maximal length in bytes.
uint16_t get_message_size(const struct GNUNET_MESSENGER_Message *message, enum GNUNET_GenericReturnValue include_header)
Returns the exact size in bytes to encode a given message.

References encode_message(), GNUNET_MESSENGER_MessageEntryStorage::entry, get_message_size(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST, GNUNET_DISK_file_seek(), GNUNET_DISK_file_write(), GNUNET_DISK_SEEK_END, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, GNUNET_MESSENGER_MessageEntryStorage::hash, key, GNUNET_MESSENGER_MessageEntry::length, GNUNET_MESSENGER_MessageEntry::offset, save(), save_message_store_attribute_failed, and value.

Referenced by save_message_store().

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

◆ save_message_store()

void save_message_store ( struct GNUNET_MESSENGER_MessageStore store)

Saves messages from a message store into its directory.

Parameters
[in]storeMessage store

Definition at line 643 of file gnunet-service-messenger_message_store.c.

644{
646 enum GNUNET_DISK_AccessPermissions permission;
647 char *filename;
648
650
651 if (! store->directory)
652 return;
653
655
657 "%s%s", store->directory, "epochs.store");
658
659 save.store = store;
661 | GNUNET_DISK_OPEN_CREATE, permission);
662
664
665 if (! save.storage)
666 {
668 "No access to local storage of message epochs!\n");
669 goto save_links;
670 }
671
672 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
674 goto close_epochs;
675
677 &save);
678
679close_epochs:
681
682save_links:
684 goto save_entries;
685
687 "%s%s", store->directory, "links.store");
688
689 save.store = store;
691 | GNUNET_DISK_OPEN_CREATE, permission);
692
694
695 if (! save.storage)
696 {
698 "No access to local storage of message links!\n");
699 goto save_entries;
700 }
701
702 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
704 goto close_links;
705
707 &save);
709
710close_links:
712
713save_entries:
715 "%s%s", store->directory, "entries.store");
716
717 save.store = store;
719 | GNUNET_DISK_OPEN_CREATE, permission);
720
722
723 if (! save.storage)
724 {
726 "No access to local storage of message entries!\n");
727 return;
728 }
729
731 {
732 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
734 goto close_entries;
735
737 &save);
739 }
740 else if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
742 goto close_entries;
743
746
748 "%s%s", store->directory, "messages.store");
749
753 permission);
754
756
758 {
761
763 GNUNET_DISK_file_sync (save.storage);
764 }
765
766close_entries:
768 save.storage = NULL;
769}
static enum GNUNET_GenericReturnValue iterate_save_entries(void *cls, const struct GNUNET_HashCode *key, void *value)
static enum GNUNET_GenericReturnValue iterate_save_links(void *cls, const struct GNUNET_HashCode *key, void *value)
static enum GNUNET_GenericReturnValue iterate_save_messages(void *cls, const struct GNUNET_HashCode *key, void *value)
static enum GNUNET_GenericReturnValue iterate_save_epochs(void *cls, const struct GNUNET_HashCode *key, void *value)
enum GNUNET_GenericReturnValue GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
Definition: disk.c:1451
@ GNUNET_DISK_OPEN_WRITE
Open the file for writing.
@ GNUNET_DISK_OPEN_CREATE
Create file if it doesn't exist.
@ GNUNET_DISK_SEEK_SET
Seek an absolute position (from the start of the file).

References GNUNET_MESSENGER_MessageStore::directory, GNUNET_MESSENGER_MessageStore::entries, GNUNET_MESSENGER_MessageStore::epochs, filename, GNUNET_asprintf(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_DISK_file_close(), GNUNET_DISK_file_open(), GNUNET_DISK_file_seek(), GNUNET_DISK_file_sync(), GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_OPEN_WRITE, GNUNET_DISK_PERM_USER_READ, GNUNET_DISK_PERM_USER_WRITE, GNUNET_DISK_SEEK_END, GNUNET_DISK_SEEK_SET, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_NO, GNUNET_SYSERR, GNUNET_YES, iterate_save_entries(), iterate_save_epochs(), iterate_save_links(), iterate_save_messages(), GNUNET_MESSENGER_MessageStore::links, GNUNET_MESSENGER_MessageStore::messages, GNUNET_MESSENGER_MessageStore::rewrite_entries, save(), GNUNET_MESSENGER_MessageStore::storage_messages, GNUNET_MESSENGER_ClosureMessageSave::store, and GNUNET_MESSENGER_MessageStore::write_links.

Referenced by save_srv_room(), and task_save_messages().

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

◆ contains_store_message()

enum GNUNET_GenericReturnValue contains_store_message ( const struct GNUNET_MESSENGER_MessageStore store,
const struct GNUNET_HashCode hash 
)

Checks if a message matching a given hash is stored in a message store.

The function returns GNUNET_YES if a match is found, GNUNET_NO otherwise.

The message has not to be loaded from disk into memory for this check!

Parameters
[in]storeMessage store
[in]hashHash of message
Returns
GNUNET_YES on match, otherwise GNUNET_NO

Definition at line 773 of file gnunet-service-messenger_message_store.c.

775{
776 GNUNET_assert ((store) && (hash));
777
779 hash))
780 return GNUNET_YES;
781
783 hash))
784 return GNUNET_YES;
785
787}

References GNUNET_MESSENGER_MessageStore::discourses, GNUNET_MESSENGER_MessageStore::entries, GNUNET_assert, GNUNET_CONTAINER_multihashmap_contains(), GNUNET_YES, GNUNET_MESSENGER_MessageStore::messages, and GNUNET_MESSENGER_ClosureMessageSave::store.

Referenced by update_room_message().

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

◆ get_store_message()

const struct GNUNET_MESSENGER_Message * get_store_message ( struct GNUNET_MESSENGER_MessageStore store,
const struct GNUNET_HashCode hash 
)

Returns the message from a message store matching a given hash.

If no matching message is found, NULL gets returned.

This function requires the message to be loaded into memory!

See also
contains_store_message()
Parameters
[in,out]storeMessage store
[in]hashHash of message
Returns
Message or NULL

Definition at line 791 of file gnunet-service-messenger_message_store.c.

793{
794 struct GNUNET_MESSENGER_Message *message;
795 const struct GNUNET_MESSENGER_MessageEntry *entry;
796 enum GNUNET_GenericReturnValue decoding;
797 struct GNUNET_HashCode check;
798 char *buffer;
799
800 GNUNET_assert ((store) && (hash));
801
802 if (GNUNET_is_zero (hash))
803 return NULL;
804
805 message = GNUNET_CONTAINER_multihashmap_get (store->messages, hash);
806
807 if (message)
808 return message;
809
810 message = GNUNET_CONTAINER_multihashmap_get (store->discourses, hash);
811
812 if (message)
813 return message;
814
815 if (! store->storage_messages)
816 {
818 "Local storage of messages is unavailable: %s\n",
819 GNUNET_h2s (hash));
820 return NULL;
821 }
822
823 entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash);
824
825 if (! entry)
826 {
828 "No entry in storage for message found: %s\n",
829 GNUNET_h2s (hash));
830 return NULL;
831 }
832
833 if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages,
834 entry->offset,
836 {
838 "Offset for message in local storage invalid: %s\n",
839 GNUNET_h2s (hash));
840 return NULL;
841 }
842
843 buffer = GNUNET_malloc (entry->length);
844
845 if (! buffer)
846 {
848 "Allocation for message data buffer failed: %s\n",
849 GNUNET_h2s (hash));
850 return NULL;
851 }
852
853 if ((GNUNET_DISK_file_read (store->storage_messages, buffer, entry->length) !=
854 entry->length) ||
856 GNUNET_YES)))
857 {
859 "Reading message from local storage failed: %s\n",
860 GNUNET_h2s (hash));
861 goto free_buffer;
862 }
863
865 decoding = decode_message (message, entry->length, buffer,
866 GNUNET_YES, NULL);
867
868 hash_message (message, entry->length, buffer, &check);
869
870 if ((GNUNET_YES != decoding) || (GNUNET_CRYPTO_hash_cmp (hash, &check) != 0))
871 {
873 "Decoding message failed or checksum mismatched: %s\n",
874 GNUNET_h2s (hash));
875
877 hash, entry))
879 "Corrupted entry could not be removed from store: %s\n",
880 GNUNET_h2s (hash));
881
883 goto free_message;
884 }
885
887 store->messages, hash, message,
889 goto free_buffer;
890
891free_message:
892 destroy_message (message);
893 message = NULL;
894
895free_buffer:
896 GNUNET_free (buffer);
897 return message;
898}
int GNUNET_CRYPTO_hash_cmp(const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2)
Compare function for HashCodes, producing a total ordering of all hashcodes.
Definition: crypto_hash.c:218
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_MESSENGER_KIND_UNKNOWN
The unknown kind.
void hash_message(const struct GNUNET_MESSENGER_Message *message, uint16_t length, const char *buffer, struct GNUNET_HashCode *hash)
Calculates a hash of a given buffer with a length in bytes from a message.
struct GNUNET_MESSENGER_Message * create_message(enum GNUNET_MESSENGER_MessageKind kind)
Creates and allocates a new message with a specific kind.
uint16_t get_message_kind_size(enum GNUNET_MESSENGER_MessageKind kind, enum GNUNET_GenericReturnValue include_header)
Returns the minimal size in bytes to encode a message of a specific kind.
enum GNUNET_GenericReturnValue decode_message(struct GNUNET_MESSENGER_Message *message, uint16_t length, const char *buffer, enum GNUNET_GenericReturnValue include_header, uint16_t *padding)
Decodes a message from a given buffer of a maximal length in bytes.

References create_message(), decode_message(), destroy_message(), GNUNET_MESSENGER_MessageStore::discourses, GNUNET_MESSENGER_MessageStore::entries, get_message_kind_size(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST, GNUNET_CRYPTO_hash_cmp(), GNUNET_DISK_file_read(), GNUNET_DISK_file_seek(), GNUNET_DISK_SEEK_SET, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_h2s(), GNUNET_is_zero, GNUNET_log, GNUNET_malloc, GNUNET_MESSENGER_KIND_UNKNOWN, GNUNET_OK, GNUNET_YES, hash_message(), GNUNET_MESSENGER_MessageEntry::length, GNUNET_MESSENGER_MessageStore::messages, GNUNET_MESSENGER_MessageEntry::offset, GNUNET_MESSENGER_MessageStore::rewrite_entries, and GNUNET_MESSENGER_MessageStore::storage_messages.

Referenced by check_srv_room_peer_status(), delete_srv_room_message(), delete_store_message(), forward_about_members(), get_store_message_link(), handle_room_messages(), iterate_epoch_session_members(), notify_about_members(), recv_message_info(), request_room_message_step(), traverse_epoch_message(), update_tunnel_last_message(), and verify_tunnel_message().

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

◆ get_store_message_link()

const struct GNUNET_MESSENGER_MessageLink * get_store_message_link ( struct GNUNET_MESSENGER_MessageStore store,
const struct GNUNET_HashCode hash,
enum GNUNET_GenericReturnValue  deleted_only 
)

Returns the message link from a message store matching a given hash.

If the flag is set to GNUNET_YES, only links from deleted messages will be returned or NULL.

Otherwise message links will also returned for messages found in the store under the given hash. The link which will be returned copies link information from the message for temporary usage.

Parameters
[in,out]storeMessage store
[in]hashHash of message
[in]deleted_onlyFlag
Returns
Message link or NULL

Definition at line 902 of file gnunet-service-messenger_message_store.c.

905{
906 const struct GNUNET_MESSENGER_Message *message;
907
908 if (GNUNET_is_zero (hash))
909 return NULL;
910
911 if (GNUNET_YES == deleted_only)
912 goto get_link;
913
914 message = get_store_message (store, hash);
915
916 if (message)
917 {
918 static struct GNUNET_MESSENGER_MessageLink link;
919
920 GNUNET_memcpy (&(link.first), &(message->header.previous),
921 sizeof(link.first));
922
923 link.multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind?
925
926 if (GNUNET_YES == link.multiple)
927 GNUNET_memcpy (&(link.second), &(message->body.merge.previous),
928 sizeof(link.second));
929 else
930 GNUNET_memcpy (&(link.second), &(message->header.previous),
931 sizeof(link.second));
932
933 return &link;
934 }
935
936get_link:
937 return GNUNET_CONTAINER_multihashmap_get (store->links, hash);
938}
const struct GNUNET_MESSENGER_Message * get_store_message(struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
Returns the message from a message store matching a given hash.
@ GNUNET_MESSENGER_KIND_MERGE
The merge kind.
struct GNUNET_MESSENGER_MessageMerge merge
struct GNUNET_HashCode previous
The hash of the previous message from the senders perspective.
enum GNUNET_MESSENGER_MessageKind kind
The kind of the message.
struct GNUNET_HashCode previous
The hash of a second previous message.
struct GNUNET_MESSENGER_MessageHeader header
Header.
struct GNUNET_MESSENGER_MessageBody body
Body.

References GNUNET_MESSENGER_Message::body, GNUNET_MESSENGER_MessageLink::first, get_store_message(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_is_zero, GNUNET_memcpy, GNUNET_MESSENGER_KIND_MERGE, GNUNET_NO, GNUNET_YES, GNUNET_MESSENGER_Message::header, GNUNET_MESSENGER_MessageHeader::kind, GNUNET_MESSENGER_MessageStore::links, GNUNET_MESSENGER_MessageBody::merge, GNUNET_MESSENGER_MessageLink::multiple, GNUNET_MESSENGER_MessageHeader::previous, GNUNET_MESSENGER_MessageMerge::previous, and GNUNET_MESSENGER_MessageLink::second.

Referenced by check_member_session_completion(), and request_room_message_step().

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

◆ get_store_message_epoch()

const struct GNUNET_HashCode * get_store_message_epoch ( const struct GNUNET_MESSENGER_MessageStore store,
const struct GNUNET_HashCode hash 
)

Returns the epoch hash of a message from a message store matching a given hash.

If no matching message is found, NULL gets returned.

Parameters
[in]storeMessage store
[in]hashHash of message
Returns
Epoch hash or NULL

Definition at line 942 of file gnunet-service-messenger_message_store.c.

944{
945 struct GNUNET_HashCode *epoch;
946
947 GNUNET_assert ((store) && (hash));
948
949 epoch = GNUNET_CONTAINER_multihashmap_get (store->epochs, hash);
950
951 if (! epoch)
952 return hash;
953
954 return epoch;
955}

References GNUNET_MESSENGER_MessageStore::epochs, GNUNET_assert, and GNUNET_CONTAINER_multihashmap_get().

Referenced by callback_found_message(), handle_room_messages(), notify_about_members(), pack_srv_room_message(), put_store_message(), and sync_srv_handle_messages().

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

◆ add_link()

static void add_link ( struct GNUNET_MESSENGER_MessageStore store,
const struct GNUNET_HashCode hash,
const struct GNUNET_MESSENGER_Message message 
)
static

Definition at line 959 of file gnunet-service-messenger_message_store.c.

962{
963 struct GNUNET_MESSENGER_MessageLink *link;
964
965 GNUNET_assert ((store) && (hash) && (message));
966
967 if (GNUNET_is_zero (hash))
968 return;
969
971
972 GNUNET_memcpy (&(link->first), &(message->header.previous),
973 sizeof(link->first));
974
977
978 if (GNUNET_YES == link->multiple)
979 GNUNET_memcpy (&(link->second), &(message->body.merge.previous),
980 sizeof(link->second));
981 else
982 GNUNET_memcpy (&(link->second), &(message->header.previous),
983 sizeof(link->second));
984
986 store->links, hash, link,
988 GNUNET_free (link);
989 else
990 store->write_links = GNUNET_YES;
991}

References GNUNET_MESSENGER_Message::body, GNUNET_MESSENGER_MessageLink::first, GNUNET_assert, GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST, GNUNET_free, GNUNET_is_zero, GNUNET_memcpy, GNUNET_MESSENGER_KIND_MERGE, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_YES, GNUNET_MESSENGER_Message::header, GNUNET_MESSENGER_MessageHeader::kind, GNUNET_MESSENGER_MessageStore::links, GNUNET_MESSENGER_MessageBody::merge, GNUNET_MESSENGER_MessageLink::multiple, GNUNET_MESSENGER_MessageHeader::previous, GNUNET_MESSENGER_MessageMerge::previous, GNUNET_MESSENGER_MessageLink::second, and GNUNET_MESSENGER_MessageStore::write_links.

Referenced by delete_store_message().

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

◆ put_store_message_epoch()

static void put_store_message_epoch ( struct GNUNET_MESSENGER_MessageStore store,
const struct GNUNET_HashCode hash,
const struct GNUNET_HashCode epoch 
)
static

Definition at line 995 of file gnunet-service-messenger_message_store.c.

998{
999 struct GNUNET_HashCode *copy;
1000
1001 GNUNET_assert ((store) && (hash) && (epoch));
1002
1003 if (GNUNET_is_zero (hash))
1004 return;
1005
1007 store->epochs, hash))
1008 return;
1009
1010 copy = GNUNET_new (struct GNUNET_HashCode);
1011
1012 if (! copy)
1013 return;
1014
1015 GNUNET_memcpy (copy, epoch, sizeof (struct GNUNET_HashCode));
1016
1018 store->epochs, hash, copy,
1020 GNUNET_free (copy);
1021}

References GNUNET_MESSENGER_MessageStore::epochs, GNUNET_assert, GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST, GNUNET_free, GNUNET_is_zero, GNUNET_memcpy, GNUNET_new, GNUNET_OK, and GNUNET_YES.

Referenced by put_store_message().

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

◆ task_save_messages()

static void task_save_messages ( void *  cls)
static

Definition at line 1025 of file gnunet-service-messenger_message_store.c.

1026{
1027 struct GNUNET_MESSENGER_MessageStore *store;
1028
1029 GNUNET_assert (cls);
1030
1031 store = cls;
1032 store->writing_task = NULL;
1033
1034 save_message_store (store);
1035}
void save_message_store(struct GNUNET_MESSENGER_MessageStore *store)
Saves messages from a message store into its directory.

References GNUNET_assert, save_message_store(), and GNUNET_MESSENGER_MessageStore::writing_task.

Referenced by put_store_message().

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

◆ put_store_message()

enum GNUNET_GenericReturnValue put_store_message ( struct GNUNET_MESSENGER_MessageStore store,
const struct GNUNET_HashCode hash,
struct GNUNET_MESSENGER_Message message 
)

Stores a message into the message store.

The result indicates if the operation was successful.

Parameters
[in,out]storeMessage store
[in]hashHash of message
[in,out]messageMessage
Returns
GNUNET_OK on success, otherwise GNUNET_NO

Definition at line 1039 of file gnunet-service-messenger_message_store.c.

1042{
1043 struct GNUNET_HashCode *epoch;
1046
1047 GNUNET_assert ((store) && (hash) && (message));
1048
1049 if (GNUNET_is_zero (hash))
1050 return GNUNET_SYSERR;
1051
1052 epoch = GNUNET_CONTAINER_multihashmap_get (store->epochs, hash);
1053
1054 if (epoch)
1055 goto reverse_epoch;
1056
1057 epoch = GNUNET_new (struct GNUNET_HashCode);
1058
1059 if (! epoch)
1060 goto skip_epoch;
1061
1062 switch (message->header.kind)
1063 {
1066 GNUNET_memcpy (epoch, hash, sizeof (struct GNUNET_HashCode));
1067 break;
1069 {
1070 const struct GNUNET_HashCode *epoch0;
1071 const struct GNUNET_HashCode *epoch1;
1072
1073 epoch0 = &(message->body.merge.epochs[0]);
1074 epoch1 = &(message->body.merge.epochs[1]);
1075
1076 if (0 == GNUNET_CRYPTO_hash_cmp (epoch0, epoch1))
1077 GNUNET_memcpy (epoch, epoch0, sizeof (struct GNUNET_HashCode));
1078 else
1079 GNUNET_memcpy (epoch, hash, sizeof (struct GNUNET_HashCode));
1080
1081 break;
1082 }
1083 default:
1085 epoch,
1086 get_store_message_epoch (store, &(message->header.previous)),
1087 sizeof (struct GNUNET_HashCode));
1088 break;
1089 }
1090
1092 store->epochs, hash, epoch,
1094 {
1095 GNUNET_free (epoch);
1096 goto skip_epoch;
1097 }
1098
1099reverse_epoch:
1100 switch (message->header.kind)
1101 {
1104 store,
1105 &(message->header.previous),
1106 &(message->body.join.epoch));
1107 break;
1110 store,
1111 &(message->header.previous),
1112 &(message->body.leave.epoch));
1113 break;
1116 store,
1117 &(message->header.previous),
1118 &(message->body.merge.epochs[0]));
1120 store,
1121 &(message->body.merge.previous),
1122 &(message->body.merge.epochs[1]));
1123 break;
1124 default:
1126 store,
1127 &(message->header.previous),
1128 epoch);
1129 break;
1130 }
1131
1132skip_epoch:
1133 map = store->messages;
1134
1135 if (get_message_discourse (message))
1136 map = store->discourses;
1137
1139 {
1141 "Message has already been stored! (%s)\n",
1142 GNUNET_h2s (hash));
1143 return GNUNET_SYSERR;
1144 }
1145
1147 map, hash, message,
1149
1150 if ((GNUNET_OK != result) || (map == store->discourses))
1151 return result;
1152
1153 if (! store->writing_task)
1157 store);
1158
1159 return result;
1160}
static void task_save_messages(void *cls)
const struct GNUNET_HashCode * get_store_message_epoch(const struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
Returns the epoch hash of a message from a message store matching a given hash.
static void put_store_message_epoch(struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash, const struct GNUNET_HashCode *epoch)
@ GNUNET_SCHEDULER_PRIORITY_BACKGROUND
Run as background job (higher than idle, lower than default).
@ GNUNET_MESSENGER_KIND_LEAVE
The leave kind.
@ GNUNET_MESSENGER_KIND_JOIN
The join kind.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_with_priority(enum GNUNET_SCHEDULER_Priority prio, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified priority.
Definition: scheduler.c:1231
const struct GNUNET_ShortHashCode * get_message_discourse(const struct GNUNET_MESSENGER_Message *message)
Returns the discourse hash of a message depending on its kind.
static struct GNUNET_CONTAINER_MultiPeerMap * map
Peermap of PeerIdentities to "struct PeerEntry" (for fast lookup).
Definition: peer.c:63
Internal representation of the hash map.
struct GNUNET_MESSENGER_MessageLeave leave
struct GNUNET_MESSENGER_MessageJoin join
struct GNUNET_HashCode epoch
The previous epoch the message was sent from.
struct GNUNET_HashCode epoch
The previous epoch the message was sent from.
struct GNUNET_HashCode epochs[2]
The previous epochs the message was sent from.

References GNUNET_MESSENGER_Message::body, GNUNET_MESSENGER_MessageStore::discourses, GNUNET_MESSENGER_MessageJoin::epoch, GNUNET_MESSENGER_MessageLeave::epoch, GNUNET_MESSENGER_MessageMerge::epochs, GNUNET_MESSENGER_MessageStore::epochs, get_message_discourse(), get_store_message_epoch(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST, GNUNET_CRYPTO_hash_cmp(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_h2s(), GNUNET_is_zero, GNUNET_log, GNUNET_memcpy, GNUNET_MESSENGER_KIND_JOIN, GNUNET_MESSENGER_KIND_LEAVE, GNUNET_MESSENGER_KIND_MERGE, GNUNET_new, GNUNET_OK, GNUNET_SCHEDULER_add_with_priority(), GNUNET_SCHEDULER_PRIORITY_BACKGROUND, GNUNET_SYSERR, GNUNET_YES, GNUNET_MESSENGER_Message::header, GNUNET_MESSENGER_MessageBody::join, GNUNET_MESSENGER_MessageHeader::kind, GNUNET_MESSENGER_MessageBody::leave, map, GNUNET_MESSENGER_MessageBody::merge, GNUNET_MESSENGER_MessageStore::messages, GNUNET_MESSENGER_MessageHeader::previous, GNUNET_MESSENGER_MessageMerge::previous, put_store_message_epoch(), result, task_save_messages(), and GNUNET_MESSENGER_MessageStore::writing_task.

Referenced by update_room_message().

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

◆ delete_store_message()

enum GNUNET_GenericReturnValue delete_store_message ( struct GNUNET_MESSENGER_MessageStore store,
const struct GNUNET_HashCode hash 
)

Deletes a message in the message store.

It will be removed from disk space and memory. The result indicates if the operation was successful.

Parameters
[in,out]storeMessage store
[in]hashHash of message
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure

Definition at line 1164 of file gnunet-service-messenger_message_store.c.

1166{
1167 const struct GNUNET_MESSENGER_MessageEntry *entry;
1168 const struct GNUNET_MESSENGER_Message *message;
1169
1170 GNUNET_assert ((store) && (hash));
1171
1172 entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash);
1173
1174 if (! entry)
1175 goto clear_memory;
1176
1177 message = get_store_message (store, hash);
1178
1179 if (message)
1180 {
1181 if (GNUNET_YES == is_epoch_message (message))
1182 {
1184 "Deletion of message is not allowed! (%s)\n",
1185 GNUNET_h2s (hash));
1186 return GNUNET_SYSERR;
1187 }
1188
1189 add_link (store, hash, message);
1190 }
1191
1192 if (! store->storage_messages)
1193 goto clear_entry;
1194
1195 if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages,
1196 entry->offset,
1198 return GNUNET_SYSERR;
1199
1200 {
1202 char *clear_buffer;
1203
1204 clear_buffer = GNUNET_malloc (entry->length);
1205
1206 if (! clear_buffer)
1207 return GNUNET_SYSERR;
1208
1209 GNUNET_CRYPTO_zero_keys (clear_buffer, entry->length);
1210
1211 if ((entry->length != GNUNET_DISK_file_write (store->storage_messages,
1212 clear_buffer, entry->length))
1213 ||
1216 else
1217 result = GNUNET_OK;
1218
1219 GNUNET_free (clear_buffer);
1220
1221 if (GNUNET_OK != result)
1222 return result;
1223 }
1224
1225clear_entry:
1227 entry))
1228 store->rewrite_entries = GNUNET_YES;
1229
1230clear_memory:
1232 return GNUNET_OK;
1233}
static void add_link(struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_Message *message)
void GNUNET_CRYPTO_zero_keys(void *buffer, size_t length)
Zero out buffer, securely against compiler optimizations.
int GNUNET_CONTAINER_multihashmap_remove_all(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Remove all entries for the given key from the map.
enum GNUNET_GenericReturnValue is_epoch_message(const struct GNUNET_MESSENGER_Message *message)
Returns whether a certain kind of message from storage contains some specific details that might be r...

References add_link(), GNUNET_MESSENGER_MessageStore::entries, get_store_message(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CONTAINER_multihashmap_remove_all(), GNUNET_CRYPTO_zero_keys(), GNUNET_DISK_file_seek(), GNUNET_DISK_file_sync(), GNUNET_DISK_file_write(), GNUNET_DISK_SEEK_SET, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_malloc, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, is_epoch_message(), GNUNET_MESSENGER_MessageEntry::length, GNUNET_MESSENGER_MessageStore::messages, GNUNET_MESSENGER_MessageEntry::offset, result, GNUNET_MESSENGER_MessageStore::rewrite_entries, and GNUNET_MESSENGER_MessageStore::storage_messages.

Referenced by callback_operation().

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

◆ iterate_flag_for_cleanup_discourse_message()

static enum GNUNET_GenericReturnValue iterate_flag_for_cleanup_discourse_message ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Definition at line 1244 of file gnunet-service-messenger_message_store.c.

1247{
1249 struct GNUNET_MESSENGER_Message *message;
1250 const struct GNUNET_ShortHashCode *discourse;
1251
1252 GNUNET_assert ((cls) && (key) && (value));
1253
1254 cleanup = cls;
1255 message = value;
1256
1257 discourse = get_message_discourse (message);
1258
1259 if ((! discourse) || (0 != GNUNET_memcmp (discourse, &(cleanup->discourse))))
1260 return GNUNET_YES;
1261
1262 {
1265
1266 if (GNUNET_TIME_absolute_cmp (timestamp, >=, cleanup->timestamp))
1267 return GNUNET_YES;
1268 }
1269
1271 destroy_message (message);
1272
1273 return GNUNET_YES;
1274}
static uint64_t timestamp(void)
Get current timestamp.
static void cleanup(void *cls)
Disconnect and shutdown.
Definition: gnunet-did.c:131
void add_to_list_messages(struct GNUNET_MESSENGER_ListMessages *messages, const struct GNUNET_HashCode *hash)
Adds a specific hash from a message to the end of the list.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:741
#define GNUNET_TIME_absolute_cmp(t1, op, t2)
Compare two absolute times.
struct GNUNET_TIME_AbsoluteNBO timestamp
The timestamp of the message.
A 256-bit hashcode.
Time for absolute times used by GNUnet, in microseconds.

References add_to_list_messages(), cleanup(), destroy_message(), get_message_discourse(), GNUNET_assert, GNUNET_memcmp, GNUNET_TIME_absolute_cmp, GNUNET_TIME_absolute_ntoh(), GNUNET_YES, GNUNET_MESSENGER_Message::header, key, GNUNET_MESSENGER_MessageHeader::timestamp, timestamp(), and value.

Referenced by cleanup_store_discourse_messages_before().

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

◆ cleanup_store_discourse_messages_before()

void cleanup_store_discourse_messages_before ( struct GNUNET_MESSENGER_MessageStore store,
const struct GNUNET_ShortHashCode discourse,
const struct GNUNET_TIME_Absolute  timestamp 
)

Cleans up and deletes all discourse messages existing in the message store memory before a certain timestamp.

Parameters
[in,out]storeMessage store
[in]discourseHash of discourse
[in]timestampTimestamp

Definition at line 1278 of file gnunet-service-messenger_message_store.c.

1284{
1287
1288 GNUNET_assert ((store) && (discourse));
1289
1291
1292 cleanup.list = &list;
1293 cleanup.timestamp = timestamp;
1294
1295 GNUNET_memcpy (&(cleanup.discourse), discourse,
1296 sizeof (struct GNUNET_ShortHashCode));
1297
1300 &cleanup);
1301
1302 {
1303 struct GNUNET_MESSENGER_ListMessage *element;
1304 for (element = list.head; element; element = element->next)
1306 store->discourses,
1307 &(element->hash));
1308 }
1309
1311}
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:68
void clear_list_messages(struct GNUNET_MESSENGER_ListMessages *messages)
Clears the list of message hashes.
void init_list_messages(struct GNUNET_MESSENGER_ListMessages *messages)
Initializes list of message hashes as empty list.
static enum GNUNET_GenericReturnValue iterate_flag_for_cleanup_discourse_message(void *cls, const struct GNUNET_HashCode *key, void *value)
struct GNUNET_MESSENGER_ListMessage * next

References cleanup(), clear_list_messages(), GNUNET_MESSENGER_CleanupDiscourseMessages::discourse, GNUNET_MESSENGER_MessageStore::discourses, GNUNET_assert, GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multihashmap_remove_all(), GNUNET_memcpy, GNUNET_MESSENGER_ListMessage::hash, init_list_messages(), iterate_flag_for_cleanup_discourse_message(), list, GNUNET_MESSENGER_ListMessage::next, and timestamp().

Referenced by cleanup_srv_room_discourse_messages().

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