GNUnet  0.17.6
Data Structures | Macros | Functions
gnunet-service-messenger_message_store.c File Reference

GNUnet MESSENGER service. More...

#include "gnunet-service-messenger_message_store.h"
#include "messenger_api_message.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
 

Macros

#define load_message_store_attribute_failed(file, attribute)    sizeof(attribute) != GNUNET_DISK_file_read(file, &(attribute), sizeof(attribute))
 
#define save_message_store_attribute_failed(file, attribute)    sizeof(attribute) != GNUNET_DISK_file_write(file, &(attribute), sizeof(attribute))
 

Functions

void init_message_store (struct GNUNET_MESSENGER_MessageStore *store)
 Initializes a message store as fully empty. More...
 
static int iterate_destroy_entries (void *cls, const struct GNUNET_HashCode *key, void *value)
 
static int iterate_destroy_messages (void *cls, const struct GNUNET_HashCode *key, void *value)
 
static int 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 int iterate_save_entries (void *cls, const struct GNUNET_HashCode *key, void *value)
 
static int iterate_save_messages (void *cls, const struct GNUNET_HashCode *key, void *value)
 
static int iterate_save_links (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...
 
int 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, int deleted_only)
 Returns the message link from a message store matching a given hash. More...
 
int 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...
 
static void add_link (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_Message *message)
 
int delete_store_message (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
 Deletes a message in the message store. More...
 

Detailed Description

GNUnet MESSENGER service.

Author
Tobias Frisch

Definition in file gnunet-service-messenger_message_store.c.

Macro Definition Documentation

◆ load_message_store_attribute_failed

#define load_message_store_attribute_failed (   file,
  attribute 
)     sizeof(attribute) != GNUNET_DISK_file_read(file, &(attribute), sizeof(attribute))

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

◆ save_message_store_attribute_failed

#define save_message_store_attribute_failed (   file,
  attribute 
)     sizeof(attribute) != GNUNET_DISK_file_write(file, &(attribute), sizeof(attribute))

Definition at line 110 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 30 of file gnunet-service-messenger_message_store.c.

31 {
32  GNUNET_assert(store);
33 
34  store->storage_messages = NULL;
35 
39 
40  store->rewrite_entries = GNUNET_NO;
41  store->write_links = GNUNET_NO;
42 }
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
@ GNUNET_NO
Definition: gnunet_common.h:98
#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

References 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 int iterate_destroy_entries ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

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

48 {
49  struct GNUNET_MESSENGER_MessageEntry *entry = value;
50 
51  GNUNET_free(entry);
52 
53  return GNUNET_YES;
54 }
static char * value
Value of the record to add/remove.
@ GNUNET_YES
#define GNUNET_free(ptr)
Wrapper around free.

References GNUNET_free, GNUNET_YES, and value.

Referenced by clear_message_store().

Here is the caller graph for this function:

◆ iterate_destroy_messages()

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

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

60 {
61  struct GNUNET_MESSENGER_Message *message = value;
62 
63  destroy_message (message);
64 
65  return GNUNET_YES;
66 }
void destroy_message(struct GNUNET_MESSENGER_Message *message)
Destroys a message and frees its memory fully.

References destroy_message(), 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 int iterate_destroy_links ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

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

72 {
73  struct GNUNET_HashCode *previous = value;
74 
75  GNUNET_free(previous);
76 
77  return GNUNET_YES;
78 }
A 512-bit hashcode.

References 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]store Message store

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

82 {
83  GNUNET_assert(store);
84 
85  if (store->storage_messages)
86  {
88 
89  store->storage_messages = NULL;
90  }
91 
95 
99 }
static int iterate_destroy_messages(void *cls, const struct GNUNET_HashCode *key, void *value)
static int iterate_destroy_entries(void *cls, const struct GNUNET_HashCode *key, void *value)
static int 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:1306
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback 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::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 114 of file gnunet-service-messenger_message_store.c.

116 {
118 
120 
121  if (!entries)
122  return;
123 
125  struct GNUNET_MESSENGER_MessageEntry *entry;
126 
127  memset(&storage, 0, sizeof(storage));
128 
129  do
130  {
131  entry = NULL;
132 
133  if ((load_message_store_attribute_failed(entries, storage.hash)) ||
134  (load_message_store_attribute_failed(entries, storage.entry.offset)) ||
135  (load_message_store_attribute_failed(entries, storage.entry.length)))
136  break;
137 
139 
140  GNUNET_memcpy(entry, &(storage.entry), sizeof(*entry));
141 
142  if ((GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->entries, &(storage.hash))) ||
143  (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->entries, &(storage.hash), entry,
145  {
146  store->rewrite_entries = GNUNET_YES;
147  break;
148  }
149  }
150  while (entry);
151 
152  if (entry)
153  GNUNET_free(entry);
154 
156 }
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:1235
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
Definition: gnunet_common.h:99
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Handle used to access files (and pipes).
struct ListEntry * entries
List of peers in the list.

References GNUNET_MESSENGER_MessageStore::entries, 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 165 of file gnunet-service-messenger_message_store.c.

167 {
169 
171 
172  if (!entries)
173  return;
174 
176  struct GNUNET_MESSENGER_MessageLink *link;
177 
178  memset(&storage, 0, sizeof(storage));
179 
180  do
181  {
182  link = NULL;
183 
184  if ((load_message_store_attribute_failed(entries, storage.hash)) ||
185  (load_message_store_attribute_failed(entries, storage.link.multiple)) ||
186  (load_message_store_attribute_failed(entries, storage.link.first)) ||
187  ((GNUNET_YES == storage.link.multiple) &&
188  (load_message_store_attribute_failed(entries, storage.link.second))))
189  break;
190 
192 
193  GNUNET_memcpy(link, &(storage.link), sizeof(*link));
194 
195  if ((GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->links, &(storage.hash))) ||
196  (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->links, &(storage.hash), link,
198  break;
199  }
200  while (link);
201 
202  if (link)
203  GNUNET_free(link);
204 
206 }

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

211 {
212  GNUNET_assert((store) && (directory));
213 
215 
216  if (store->storage_messages)
218 
219  char *filename;
220  GNUNET_asprintf (&filename, "%s%s", directory, "messages.store");
221 
224  else
225  store->storage_messages = NULL;
226 
228 
229  if (!store->storage_messages)
230  return;
231 
232  GNUNET_asprintf (&filename, "%s%s", directory, "entries.store");
233 
236 
238 
239  GNUNET_asprintf (&filename, "%s%s", directory, "links.store");
240 
243 
245 }
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:482
@ 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_entries()

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

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

258 {
260  struct GNUNET_MESSENGER_MessageEntry *entry = value;
261 
263 
264  GNUNET_DISK_file_write (save->storage, key, sizeof(*key));
265  GNUNET_DISK_file_write (save->storage, &(entry->offset), sizeof(entry->offset));
266  GNUNET_DISK_file_write (save->storage, &(entry->length), sizeof(entry->length));
267 
268  return GNUNET_YES;
269 }
struct GNUNET_HashCode key
The key used in the DHT.
static void save()
Write persistent statistics to disk.
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:686

References GNUNET_MESSENGER_MessageEntryStorage::entry, GNUNET_DISK_file_write(), GNUNET_YES, key, GNUNET_MESSENGER_MessageEntry::length, GNUNET_MESSENGER_MessageEntry::offset, save(), 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 int iterate_save_messages ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

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

275 {
277 
278  if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (save->store->entries, key))
279  return GNUNET_YES;
280 
281  struct GNUNET_MESSENGER_Message *message = value;
283 
284  GNUNET_memcpy(&(storage.hash), key, sizeof(storage.hash));
285 
286  storage.entry.length = get_message_size (message, GNUNET_YES);
287  storage.entry.offset = GNUNET_DISK_file_seek (save->store->storage_messages, 0, GNUNET_DISK_SEEK_END);
288 
289  if ((GNUNET_SYSERR == storage.entry.offset) ||
290  (save_message_store_attribute_failed(save->storage, storage.hash)) ||
291  (save_message_store_attribute_failed(save->storage, storage.entry.offset)) ||
292  (save_message_store_attribute_failed(save->storage, storage.entry.length)))
293  return GNUNET_YES;
294 
295  char *buffer = GNUNET_malloc(storage.entry.length);
296 
297  encode_message (message, storage.entry.length, buffer, GNUNET_YES);
298 
299  GNUNET_DISK_file_write (save->store->storage_messages, buffer, storage.entry.length);
300 
301  GNUNET_free(buffer);
302  return GNUNET_YES;
303 }
#define save_message_store_attribute_failed(file, attribute)
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.
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
#define GNUNET_malloc(size)
Wrapper around malloc.
void encode_message(const struct GNUNET_MESSENGER_Message *message, uint16_t length, char *buffer, int 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, int include_header)
Returns the exact size in bytes to encode a given message.

References encode_message(), GNUNET_MESSENGER_MessageEntryStorage::entry, get_message_size(), GNUNET_CONTAINER_multihashmap_contains(), GNUNET_DISK_file_seek(), GNUNET_DISK_file_write(), GNUNET_DISK_SEEK_END, GNUNET_free, 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:

◆ iterate_save_links()

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

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

309 {
311  struct GNUNET_MESSENGER_MessageLink *link = value;
312 
313  GNUNET_DISK_file_write (save->storage, key, sizeof(*key));
314  GNUNET_DISK_file_write (save->storage, &(link->multiple), sizeof(link->multiple));
315  GNUNET_DISK_file_write (save->storage, &(link->first), sizeof(link->first));
316 
317  if (GNUNET_YES == link->multiple)
318  GNUNET_DISK_file_write (save->storage, &(link->second), sizeof(link->second));
319 
320  return GNUNET_YES;
321 }

References GNUNET_MESSENGER_MessageLink::first, GNUNET_DISK_file_write(), GNUNET_YES, key, GNUNET_MESSENGER_MessageLink::multiple, save(), 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:

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

326 {
327  GNUNET_assert((store) && (directory));
328 
330 
332 
333  char *filename;
334 
335  if (GNUNET_YES != store->write_links)
336  goto save_entries;
337 
338  GNUNET_asprintf (&filename, "%s%s", directory, "links.store");
339 
340  save.store = store;
342 
344 
345  if (!save.storage)
346  goto save_entries;
347 
349  goto close_links;
350 
353 
354 close_links:
355  GNUNET_DISK_file_close (save.storage);
356 
357 save_entries:
358  GNUNET_asprintf (&filename, "%s%s", directory, "entries.store");
359 
360  save.store = store;
362 
364 
365  if (!save.storage)
366  return;
367 
369  {
371  goto close_entries;
372 
375  }
377  goto close_entries;
378 
379  if (store->storage_messages)
381 
382  GNUNET_asprintf (&filename, "%s%s", directory, "messages.store");
383 
385  permission);
386 
388 
389  if (store->storage_messages)
390  {
392 
394  GNUNET_DISK_file_sync (save.storage);
395  }
396 
397 close_entries:
398  GNUNET_DISK_file_close (save.storage);
399 }
static int iterate_save_messages(void *cls, const struct GNUNET_HashCode *key, void *value)
static int iterate_save_entries(void *cls, const struct GNUNET_HashCode *key, void *value)
static int iterate_save_links(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:1425
@ 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()

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

404 {
405  GNUNET_assert((store) && (hash));
406 
408  return GNUNET_YES;
409 
410  return GNUNET_CONTAINER_multihashmap_contains (store->entries, hash);
411 }

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

Here is the call 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]store Message store
[in]hashHash of message
Returns
Message or NULL

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

416 {
417  GNUNET_assert((store) && (hash));
418 
420 
421  if (message)
422  return message;
423 
424  if (!store->storage_messages)
425  return NULL;
426 
427  const struct GNUNET_MESSENGER_MessageEntry *entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash);
428 
429  if (!entry)
430  return NULL;
431 
433  return message;
434 
435  char *buffer = GNUNET_malloc(entry->length);
436 
437  if (!buffer)
438  return NULL;
439 
440  if ((GNUNET_DISK_file_read (store->storage_messages, buffer, entry->length) != entry->length) ||
442  goto free_buffer;
443 
445 
446  const int decoding = decode_message (message, entry->length, buffer, GNUNET_YES, NULL);
447 
448  struct GNUNET_HashCode check;
449  hash_message (message, entry->length, buffer, &check);
450 
451  if ((GNUNET_YES != decoding) || (GNUNET_CRYPTO_hash_cmp (hash, &check) != 0))
452  {
453  if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (store->entries, hash, entry))
454  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Corrupted entry could not be removed from store: %s\n",
455  GNUNET_h2s(hash));
456 
457  store->rewrite_entries = GNUNET_YES;
458 
459  goto free_message;
460  }
461 
462  if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (store->messages, hash, message,
464  goto free_buffer;
465 
466 free_message: destroy_message (message);
467  message = NULL;
468 
469 free_buffer:
470  GNUNET_free(buffer);
471 
472  return message;
473 }
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:622
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:220
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.
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.
#define GNUNET_log(kind,...)
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_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.
int decode_message(struct GNUNET_MESSENGER_Message *message, uint16_t length, const char *buffer, int include_header, uint16_t *padding)
Decodes a message from a given buffer of a maximal length in bytes.
uint16_t get_message_kind_size(enum GNUNET_MESSENGER_MessageKind kind, int include_header)
Returns the minimal size in bytes to encode a message of a specific kind.
struct GNUNET_MESSENGER_Message * create_message(enum GNUNET_MESSENGER_MessageKind kind)
Creates and allocates a new message with a specific kind.

References create_message(), decode_message(), destroy_message(), 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 callback_verify_room_message(), check_srv_room_peer_status(), delete_srv_room_message(), forward_about_members(), get_store_message_link(), handle_room_messages(), notify_about_members(), request_room_message_step(), update_room_message(), and update_tunnel_last_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,
int  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]store Message store
[in]hashHash of message
[in]deleted_onlyFlag
Returns
Message link or NULL

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

479 {
480  if (deleted_only)
481  goto get_link;
482 
483  const struct GNUNET_MESSENGER_Message *message = get_store_message(store, hash);
484 
485  if (!message)
486  goto get_link;
487 
488  static struct GNUNET_MESSENGER_MessageLink link;
489 
490  GNUNET_memcpy(&(link.first), &(message->header.previous), sizeof(link.first));
491 
492  link.multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind? GNUNET_YES : GNUNET_NO;
493 
494  if (GNUNET_YES == link.multiple)
495  GNUNET_memcpy(&(link.second), &(message->body.merge.previous), sizeof(link.second));
496  else
497  GNUNET_memcpy(&(link.second), &(message->header.previous), sizeof(link.second));
498 
499  return &link;
500 
501 get_link:
502  return GNUNET_CONTAINER_multihashmap_get (store->links, hash);
503 }
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:

◆ put_store_message()

int 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]store Message store
[in]hashHash of message
[in/out]message Message
Returns
GNUNET_OK on success, otherwise GNUNET_NO

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

509 {
510  GNUNET_assert((store) && (hash) && (message));
511 
512  return GNUNET_CONTAINER_multihashmap_put (store->messages, hash, message,
514 }

References GNUNET_assert, GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST, 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:

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

520 {
522 
523  GNUNET_memcpy(&(link->first), &(message->header.previous), sizeof(link->first));
524 
526 
527  if (GNUNET_YES == link->multiple)
528  GNUNET_memcpy(&(link->second), &(message->body.merge.previous), sizeof(link->second));
529  else
530  GNUNET_memcpy(&(link->second), &(message->header.previous), sizeof(link->second));
531 
532  if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(store->links, hash, link,
534  GNUNET_free(link);
535 }

References GNUNET_MESSENGER_Message::body, GNUNET_MESSENGER_MessageLink::first, 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, and GNUNET_MESSENGER_MessageLink::second.

Here is the call graph for this function:

◆ delete_store_message()

int 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]store Message store
[in]hashHash of message
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure

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

540 {
541  GNUNET_assert((store) && (hash));
542 
543  const struct GNUNET_MESSENGER_MessageEntry *entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash);
544 
545  if (!entry)
546  goto clear_memory;
547 
548  const struct GNUNET_MESSENGER_Message *message = get_store_message(store, hash);
549 
550  if (message)
551  add_link (store, hash, message);
552 
553  if (!store->storage_messages)
554  goto clear_entry;
555 
557  return GNUNET_SYSERR;
558 
559  char *clear_buffer = GNUNET_malloc(entry->length);
560 
561  if (!clear_buffer)
562  return GNUNET_SYSERR;
563 
564  GNUNET_CRYPTO_zero_keys (clear_buffer, entry->length);
565 
566  if ((entry->length != GNUNET_DISK_file_write (store->storage_messages, clear_buffer, entry->length)) || (GNUNET_OK
568  {
569  GNUNET_free(clear_buffer);
570  return GNUNET_SYSERR;
571  }
572 
573  GNUNET_free(clear_buffer);
574 
575 clear_entry:
576  if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (store->entries, hash, entry))
577  store->rewrite_entries = GNUNET_YES;
578 
579 clear_memory:
581  return GNUNET_OK;
582 }
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.

Referenced by callback_room_deletion().

Here is the caller graph for this function: