GNUnet 0.22.2
gnunet-service-messenger_message_store.c File Reference
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)
 
#define save_message_store_attribute_failed(file, attribute)
 

Functions

void init_message_store (struct GNUNET_MESSENGER_MessageStore *store)
 Initializes a message store as fully empty. 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_links (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...
 
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)
 
void load_message_store (struct GNUNET_MESSENGER_MessageStore *store, const char *directory)
 Loads messages from a directory into a message store. More...
 
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, const char *directory)
 Saves messages from a message store into a 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...
 
static void add_link (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_Message *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. 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 
)
Value:
sizeof(attribute) != GNUNET_DISK_file_read (file, &(attribute), \
sizeof(attribute))
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:646

Definition at line 131 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:682

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

Function Documentation

◆ init_message_store()

void init_message_store ( struct GNUNET_MESSENGER_MessageStore store)

Initializes a message store as fully empty.

Parameters
[out]storeMessage store

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

34{
35 GNUNET_assert (store);
36
37 store->storage_messages = NULL;
38
43
45 store->write_links = GNUNET_NO;
46}
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.
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 * discourses

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

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 50 of file gnunet-service-messenger_message_store.c.

53{
55
57
58 entry = value;
59
60 GNUNET_free (entry);
61 return GNUNET_YES;
62}
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 66 of file gnunet-service-messenger_message_store.c.

69{
70 struct GNUNET_MESSENGER_Message *message;
71
73
74 message = value;
75
76 destroy_message (message);
77 return GNUNET_YES;
78}
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_links()

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

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

85{
86 struct GNUNET_HashCode *previous;
87
89
90 previous = value;
91
92 GNUNET_free (previous);
93 return GNUNET_YES;
94}
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 98 of file gnunet-service-messenger_message_store.c.

99{
100 GNUNET_assert (store);
101
102 if (store->storage_messages)
103 {
105
106 store->storage_messages = NULL;
107 }
108
114 NULL);
117
122}
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_links(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:1289
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.

References GNUNET_MESSENGER_MessageStore::discourses, GNUNET_MESSENGER_MessageStore::entries, GNUNET_assert, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_DISK_file_close(), iterate_destroy_entries(), iterate_destroy_links(), iterate_destroy_messages(), GNUNET_MESSENGER_MessageStore::links, GNUNET_MESSENGER_MessageStore::messages, and GNUNET_MESSENGER_MessageStore::storage_messages.

Referenced by destroy_srv_room().

Here is the call graph for this function:
Here is the caller 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 140 of file gnunet-service-messenger_message_store.c.

142{
143 enum GNUNET_DISK_AccessPermissions permission;
144 struct GNUNET_DISK_FileHandle *entries;
146 struct GNUNET_MESSENGER_MessageEntry *entry;
147
148 permission = (GNUNET_DISK_PERM_USER_READ);
150 permission);
151
152 if (! entries)
153 return;
154
155 memset (&storage, 0, sizeof(storage));
156
157 do
158 {
159 entry = NULL;
160
161 if ((load_message_store_attribute_failed (entries, storage.hash)) ||
162 (load_message_store_attribute_failed (entries, storage.entry.offset)) ||
163 (load_message_store_attribute_failed (entries, storage.entry.length)))
164 break;
165
167
168 GNUNET_memcpy (entry, &(storage.entry), sizeof(*entry));
169
171 &(storage.hash)))
172 ||
174 &(storage.hash), entry,
176 {
178 break;
179 }
180 }
181 while (entry);
182
183 if (entry)
184 GNUNET_free (entry);
185
186 GNUNET_DISK_file_close (entries);
187}
static char * filename
#define load_message_store_attribute_failed(file, attribute)
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:1215
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
#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_OPEN_READ, GNUNET_DISK_PERM_USER_READ, GNUNET_free, GNUNET_memcpy, GNUNET_new, GNUNET_OK, GNUNET_YES, GNUNET_MESSENGER_MessageEntryStorage::hash, GNUNET_MESSENGER_MessageEntry::length, load_message_store_attribute_failed, GNUNET_MESSENGER_MessageEntry::offset, and GNUNET_MESSENGER_MessageStore::rewrite_entries.

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 197 of file gnunet-service-messenger_message_store.c.

199{
200 enum GNUNET_DISK_AccessPermissions permission;
201 struct GNUNET_DISK_FileHandle *entries;
203 struct GNUNET_MESSENGER_MessageLink *link;
204
205 permission = (GNUNET_DISK_PERM_USER_READ);
206
208 permission);
209
210 if (! entries)
211 return;
212
213 memset (&storage, 0, sizeof(storage));
214
215 do
216 {
217 link = NULL;
218
219 if ((load_message_store_attribute_failed (entries, storage.hash)) ||
221 storage.link.multiple)) ||
222 (load_message_store_attribute_failed (entries, storage.link.first)) ||
223 ((GNUNET_YES == storage.link.multiple) &&
224 (load_message_store_attribute_failed (entries, storage.link.second))))
225 break;
226
228
229 GNUNET_memcpy (link, &(storage.link), sizeof(*link));
230
232 &(storage.hash)))
233 ||
235 &(storage.hash), link,
237
238 break;
239 }
240 while (link);
241
242 if (link)
243 GNUNET_free (link);
244
245 GNUNET_DISK_file_close (entries);
246}

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_OPEN_READ, GNUNET_DISK_PERM_USER_READ, GNUNET_free, GNUNET_memcpy, GNUNET_new, GNUNET_OK, GNUNET_YES, GNUNET_MESSENGER_MessageLinkStorage::hash, GNUNET_MESSENGER_MessageLinkStorage::link, GNUNET_MESSENGER_MessageStore::links, load_message_store_attribute_failed, GNUNET_MESSENGER_MessageLink::multiple, and GNUNET_MESSENGER_MessageLink::second.

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,
const char *  directory 
)

Loads messages from a directory into a message store.

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

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

252{
253 enum GNUNET_DISK_AccessPermissions permission;
254 char *filename;
255
256 GNUNET_assert ((store) && (directory));
257
259
260 if (store->storage_messages)
262
263 GNUNET_asprintf (&filename, "%s%s", directory, "messages.store");
264
268 permission);
269 else
270 store->storage_messages = NULL;
271
273
274 if (! store->storage_messages)
275 return;
276
277 GNUNET_asprintf (&filename, "%s%s", directory, "entries.store");
278
281
283
284 GNUNET_asprintf (&filename, "%s%s", directory, "links.store");
285
288
290}
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)
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:506
@ 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 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_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_links()

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

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

304{
306 struct GNUNET_MESSENGER_MessageLink *link;
307
308 GNUNET_assert ((cls) && (key) && (value));
309
310 save = cls;
311 link = value;
312
313 if ((save_message_store_attribute_failed (save->storage, (*key))) ||
316 return GNUNET_NO;
317
318 if ((GNUNET_YES == link->multiple) &&
320 return GNUNET_NO;
321
322 return GNUNET_YES;
323}
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_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 327 of file gnunet-service-messenger_message_store.c.

330{
332 struct GNUNET_MESSENGER_MessageEntry *entry;
333
334 GNUNET_assert ((cls) && (key) && (value));
335
336 save = cls;
337 entry = value;
338
339 if ((save_message_store_attribute_failed (save->storage, (*key))) ||
340 (save_message_store_attribute_failed (save->storage, entry->offset)) ||
342 return GNUNET_NO;
343
344 return GNUNET_YES;
345}

References GNUNET_assert, 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 349 of file gnunet-service-messenger_message_store.c.

352{
355 struct GNUNET_MESSENGER_Message *message;
356
357 GNUNET_assert ((cls) && (key) && (value));
358
359 save = cls;
360
362 key))
363 return GNUNET_YES;
364
365 message = value;
366
367 GNUNET_memcpy (&(storage.hash), key, sizeof(storage.hash));
368
369 storage.entry.length = get_message_size (message, GNUNET_YES);
370 storage.entry.offset = GNUNET_DISK_file_seek (save->store->storage_messages,
372
373 if ((GNUNET_SYSERR == storage.entry.offset) ||
374 (save_message_store_attribute_failed (save->storage, storage.hash)) ||
376 storage.entry.offset)) ||
378 storage.entry.length)))
379 return GNUNET_NO;
380
381 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing message with hash: %s\n",
382 GNUNET_h2s (&(storage.hash)));
383
384 {
385 char *buffer;
386 buffer = GNUNET_malloc (storage.entry.length);
387
388 encode_message (message, storage.entry.length, buffer, GNUNET_YES);
389
390 GNUNET_DISK_file_write (save->store->storage_messages, buffer,
391 storage.entry.length);
392
393 GNUNET_free (buffer);
394 }
395
396 return GNUNET_YES;
397}
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:206
@ GNUNET_DISK_SEEK_END
Seek an absolute position from the end of the file.
#define GNUNET_log(kind,...)
@ GNUNET_SYSERR
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_DEBUG
#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_DISK_file_seek(), GNUNET_DISK_file_write(), GNUNET_DISK_SEEK_END, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_NO, 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,
const char *  directory 
)

Saves messages from a message store into a directory.

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

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

403{
405 enum GNUNET_DISK_AccessPermissions permission;
406 char *filename;
407
408 GNUNET_assert ((store) && (directory));
409
411
413 goto save_entries;
414
415 GNUNET_asprintf (&filename, "%s%s", directory, "links.store");
416
417 save.store = store;
419 | GNUNET_DISK_OPEN_CREATE, permission);
420
422
423 if (! save.storage)
424 goto save_entries;
425
426 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
428 goto close_links;
429
431 &save);
433
434close_links:
436
437save_entries:
438 GNUNET_asprintf (&filename, "%s%s", directory, "entries.store");
439
440 save.store = store;
442 | GNUNET_DISK_OPEN_CREATE, permission);
443
445
446 if (! save.storage)
447 return;
448
450 {
451 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
453 goto close_entries;
454
456 &save);
458 }
459 else if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
461 goto close_entries;
462
465
466 GNUNET_asprintf (&filename, "%s%s", directory, "messages.store");
467
471 permission);
472
474
476 {
479
481 GNUNET_DISK_file_sync (save.storage);
482 }
483
484close_entries:
486}
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)
enum GNUNET_GenericReturnValue GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
Definition: disk.c:1408
@ 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::entries, 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_free, GNUNET_NO, GNUNET_SYSERR, GNUNET_YES, iterate_save_entries(), 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().

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 490 of file gnunet-service-messenger_message_store.c.

492{
493 GNUNET_assert ((store) && (hash));
494
496 hash))
497 return GNUNET_YES;
498
500 hash))
501 return GNUNET_YES;
502
504}

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 508 of file gnunet-service-messenger_message_store.c.

510{
511 struct GNUNET_MESSENGER_Message *message;
512 const struct GNUNET_MESSENGER_MessageEntry *entry;
513 enum GNUNET_GenericReturnValue decoding;
514 struct GNUNET_HashCode check;
515 char *buffer;
516
517 GNUNET_assert ((store) && (hash));
518
519 message = GNUNET_CONTAINER_multihashmap_get (store->messages, hash);
520
521 if (message)
522 return message;
523
524 message = GNUNET_CONTAINER_multihashmap_get (store->discourses, hash);
525
526 if (message)
527 return message;
528
529 if (! store->storage_messages)
530 return NULL;
531
532 entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash);
533
534 if (! entry)
535 return NULL;
536
537 if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages,
538 entry->offset,
540 return message;
541
542 buffer = GNUNET_malloc (entry->length);
543
544 if (! buffer)
545 return NULL;
546
547 if ((GNUNET_DISK_file_read (store->storage_messages, buffer, entry->length) !=
548 entry->length) ||
550 GNUNET_YES)))
551 goto free_buffer;
552
554 decoding = decode_message (message, entry->length, buffer,
555 GNUNET_YES, NULL);
556
557 hash_message (message, entry->length, buffer, &check);
558
559 if ((GNUNET_YES != decoding) || (GNUNET_CRYPTO_hash_cmp (hash, &check) != 0))
560 {
562 hash, entry))
564 "Corrupted entry could not be removed from store: %s\n",
565 GNUNET_h2s (hash));
566
568
569 goto free_message;
570 }
571
573 message,
575
576 goto free_buffer;
577
578 free_message : destroy_message (message);
579 message = NULL;
580
581free_buffer:
582 GNUNET_free (buffer);
583
584 return message;
585}
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.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_ERROR_TYPE_WARNING
@ 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_WARNING, GNUNET_free, GNUNET_h2s(), 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(), notify_about_members(), recv_message_info(), request_room_message_step(), 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 589 of file gnunet-service-messenger_message_store.c.

592{
593 const struct GNUNET_MESSENGER_Message *message;
594
595 if (deleted_only)
596 goto get_link;
597
598 message = get_store_message (store, hash);
599
600 if (message)
601 {
602 static struct GNUNET_MESSENGER_MessageLink link;
603
604 GNUNET_memcpy (&(link.first), &(message->header.previous),
605 sizeof(link.first));
606
607 link.multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind?
609
610 if (GNUNET_YES == link.multiple)
611 GNUNET_memcpy (&(link.second), &(message->body.merge.previous),
612 sizeof(link.second));
613 else
614 GNUNET_memcpy (&(link.second), &(message->header.previous),
615 sizeof(link.second));
616
617 return &link;
618 }
619
620get_link:
621 return GNUNET_CONTAINER_multihashmap_get (store->links, hash);
622}
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_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:

◆ 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 626 of file gnunet-service-messenger_message_store.c.

629{
630 struct GNUNET_MESSENGER_MessageLink *link;
631
632 GNUNET_assert ((store) && (hash) && (message));
633
635
636 GNUNET_memcpy (&(link->first), &(message->header.previous),
637 sizeof(link->first));
638
641
642 if (GNUNET_YES == link->multiple)
643 GNUNET_memcpy (&(link->second), &(message->body.merge.previous),
644 sizeof(link->second));
645 else
646 GNUNET_memcpy (&(link->second), &(message->header.previous),
647 sizeof(link->second));
648
649 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->links, hash, link,
651
652 GNUNET_free (link);
653 else
654 store->write_links = GNUNET_YES;
655}

References GNUNET_MESSENGER_Message::body, GNUNET_MESSENGER_MessageLink::first, GNUNET_assert, GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST, GNUNET_free, 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()

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 659 of file gnunet-service-messenger_message_store.c.

662{
664
665 GNUNET_assert ((store) && (hash) && (message));
666
667 map = store->messages;
668
669 if (get_message_discourse (message))
670 map = store->discourses;
671
672 return GNUNET_CONTAINER_multihashmap_put (map, hash, message,
674}
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.

References GNUNET_MESSENGER_MessageStore::discourses, get_message_discourse(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST, map, and GNUNET_MESSENGER_MessageStore::messages.

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 678 of file gnunet-service-messenger_message_store.c.

680{
681 const struct GNUNET_MESSENGER_MessageEntry *entry;
682
683 GNUNET_assert ((store) && (hash));
684
685 entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash);
686
687 if (! entry)
688 goto clear_memory;
689
690 {
691 const struct GNUNET_MESSENGER_Message *message;
692 message = get_store_message (store, hash);
693
694 if (message)
695 add_link (store, hash, message);
696 }
697
698 if (! store->storage_messages)
699 goto clear_entry;
700
701 if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages,
702 entry->offset,
704 return GNUNET_SYSERR;
705
706 {
707 char *clear_buffer;
708 clear_buffer = GNUNET_malloc (entry->length);
709
710 if (! clear_buffer)
711 return GNUNET_SYSERR;
712
713 GNUNET_CRYPTO_zero_keys (clear_buffer, entry->length);
714
715 if ((entry->length != GNUNET_DISK_file_write (store->storage_messages,
716 clear_buffer, entry->length)) ||
717 (GNUNET_OK
718 !=
720 store->storage_messages)))
721 {
722 GNUNET_free (clear_buffer);
723 return GNUNET_SYSERR;
724 }
725
726 GNUNET_free (clear_buffer);
727 }
728
729clear_entry:
731 entry))
733
734clear_memory:
736 return GNUNET_OK;
737}
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.

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_free, GNUNET_malloc, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, 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 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 748 of file gnunet-service-messenger_message_store.c.

751{
753 struct GNUNET_MESSENGER_Message *message;
754 const struct GNUNET_ShortHashCode *discourse;
755
756 GNUNET_assert ((cls) && (key) && (value));
757
758 cleanup = cls;
759 message = value;
760
761 discourse = get_message_discourse (message);
762
763 if ((! discourse) || (0 != GNUNET_memcmp (discourse, &(cleanup->discourse))))
764 return GNUNET_YES;
765
766 {
769
770 if (GNUNET_TIME_absolute_cmp(timestamp, >=, cleanup->timestamp))
771 return GNUNET_YES;
772 }
773
775 destroy_message(message);
776
777 return GNUNET_YES;
778}
static uint64_t timestamp(void)
Get current timestamp.
static void cleanup(void *cls)
Disconnect and shutdown.
Definition: gnunet-did.c:130
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 781 of file gnunet-service-messenger_message_store.c.

784{
787
788 GNUNET_assert ((store) && (discourse));
789
791
792 cleanup.list = &list;
793 cleanup.timestamp = timestamp;
794
795 GNUNET_memcpy (&(cleanup.discourse), discourse,
796 sizeof (struct GNUNET_ShortHashCode));
797
800 &cleanup);
801
802 {
803 struct GNUNET_MESSENGER_ListMessage *element;
804 for (element = list.head; element; element = element->next)
806 }
807
809}
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: