GNUnet  0.11.x
Data Structures | 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
 

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.

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 }
@ GNUNET_NO
Definition: gnunet_common.h:94
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
#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_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
Definition: gnunet_common.h:97
#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_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 108 of file gnunet-service-messenger_message_store.c.

110 {
112 
114 
115  if (!entries)
116  return;
117 
119  struct GNUNET_MESSENGER_MessageEntry *entry;
120 
121  do
122  {
124 
125  if (GNUNET_DISK_file_read (entries, &storage, sizeof(storage)) == sizeof(storage))
126  {
127  GNUNET_memcpy(entry, &(storage.entry), sizeof(*entry));
128 
129  if ((GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->entries, &(storage.hash))) ||
130  (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->entries, &(storage.hash), entry,
132  {
133  store->rewrite_entries = GNUNET_YES;
134  GNUNET_free(entry);
135  }
136  }
137  else
138  {
139  GNUNET_free(entry);
140 
141  entry = NULL;
142  }
143  }
144  while (entry);
145 
147 }
static char * filename
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
Definition: gnunet_common.h:95
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.
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
@ GNUNET_DISK_OPEN_READ
Open the file for reading.
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
int 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).
int 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_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_file_read(), GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_USER_READ, GNUNET_free, GNUNET_memcpy, GNUNET_new, GNUNET_OK, GNUNET_YES, GNUNET_MESSENGER_MessageEntryStorage::hash, 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 156 of file gnunet-service-messenger_message_store.c.

158 {
160 
162 
163  if (!entries)
164  return;
165 
167  struct GNUNET_MESSENGER_MessageLink *link = NULL;
168 
169  memset(&storage, 0, sizeof(storage));
170 
171  do
172  {
173  if ((sizeof(storage.hash) != GNUNET_DISK_file_read (entries, &(storage.hash), sizeof(storage.hash))) ||
174  (sizeof(storage.link.multiple) != GNUNET_DISK_file_read (entries, &(storage.link.multiple), sizeof(storage.link.multiple))) ||
175  (sizeof(storage.link.first) != GNUNET_DISK_file_read (entries, &(storage.link.first), sizeof(storage.link.first))) ||
176  ((GNUNET_YES == storage.link.multiple) &&
177  (sizeof(storage.link.second) != GNUNET_DISK_file_read (entries, &(storage.link.second), sizeof(storage.link.second)))))
178  break;
179 
181 
182  GNUNET_memcpy(link, &(storage.link), sizeof(*link));
183 
184  if ((GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->links, &(storage.hash))) ||
185  (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->links, &(storage.hash), link,
187  break;
188  }
189  while (link);
190 
191  if (link)
192  GNUNET_free(link);
193 
195 }

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_file_read(), 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, 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 198 of file gnunet-service-messenger_message_store.c.

200 {
201  GNUNET_assert((store) && (directory));
202 
204 
205  if (store->storage_messages)
207 
208  char *filename;
209  GNUNET_asprintf (&filename, "%s%s", directory, "messages.store");
210 
213  else
214  store->storage_messages = NULL;
215 
217 
218  if (!store->storage_messages)
219  return;
220 
221  GNUNET_asprintf (&filename, "%s%s", directory, "entries.store");
222 
225 
227 
228  GNUNET_asprintf (&filename, "%s%s", directory, "links.store");
229 
232 
234 }
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_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 244 of file gnunet-service-messenger_message_store.c.

247 {
249  struct GNUNET_MESSENGER_MessageEntry *entry = value;
250 
252 
253  GNUNET_memcpy(&(storage.hash), key, sizeof(storage.hash));
254  GNUNET_memcpy(&(storage.entry), entry, sizeof(*entry));
255 
256  GNUNET_DISK_file_write (save->storage, &storage, sizeof(storage));
257 
258  return GNUNET_YES;
259 }
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_memcpy, GNUNET_YES, GNUNET_MESSENGER_MessageEntryStorage::hash, key, 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 262 of file gnunet-service-messenger_message_store.c.

265 {
267 
268  if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (save->store->entries, key))
269  return GNUNET_YES;
270 
271  struct GNUNET_MESSENGER_Message *message = value;
273 
274  GNUNET_memcpy(&(storage.hash), key, sizeof(storage.hash));
275 
276  storage.entry.length = get_message_size (message, GNUNET_YES);
277  storage.entry.offset = GNUNET_DISK_file_seek (save->store->storage_messages, 0, GNUNET_DISK_SEEK_END);
278 
279  if ((GNUNET_SYSERR == storage.entry.offset) || (sizeof(storage)
280  != GNUNET_DISK_file_write (save->storage, &storage, sizeof(storage))))
281  return GNUNET_YES;
282 
283  char *buffer = GNUNET_malloc(storage.entry.length);
284 
285  encode_message (message, storage.entry.length, buffer, GNUNET_YES);
286 
287  GNUNET_DISK_file_write (save->store->storage_messages, buffer, storage.entry.length);
288 
289  GNUNET_free(buffer);
290 
291  return GNUNET_YES;
292 }
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
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_malloc(size)
Wrapper around malloc.
uint16_t get_message_size(const struct GNUNET_MESSENGER_Message *message, int include_signature)
Returns the exact size in bytes to encode a given message.
void encode_message(const struct GNUNET_MESSENGER_Message *message, uint16_t length, char *buffer, int include_signature)
Encodes a given message into a buffer of a maximal length in bytes.

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(), 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 295 of file gnunet-service-messenger_message_store.c.

298 {
300  struct GNUNET_MESSENGER_MessageLink *link = value;
301 
302  GNUNET_DISK_file_write (save->storage, key, sizeof(*key));
303  GNUNET_DISK_file_write (save->storage, &(link->multiple), sizeof(link->multiple));
304  GNUNET_DISK_file_write (save->storage, &(link->first), sizeof(link->first));
305 
306  if (GNUNET_YES == link->multiple)
307  GNUNET_DISK_file_write (save->storage, &(link->second), sizeof(link->second));
308 
309  return GNUNET_YES;
310 }

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

315 {
316  GNUNET_assert((store) && (directory));
317 
319 
321 
322  char *filename;
323 
324  if (GNUNET_YES != store->write_links)
325  goto save_entries;
326 
327  GNUNET_asprintf (&filename, "%s%s", directory, "links.store");
328 
329  save.store = store;
331 
333 
334  if (!save.storage)
335  goto save_entries;
336 
338  goto close_links;
339 
342 
343 close_links:
344  GNUNET_DISK_file_close (save.storage);
345 
346 save_entries:
347  GNUNET_asprintf (&filename, "%s%s", directory, "entries.store");
348 
349  save.store = store;
351 
353 
354  if (!save.storage)
355  return;
356 
358  {
360  goto close_entries;
361 
364  }
366  goto close_entries;
367 
368  if (store->storage_messages)
370 
371  GNUNET_asprintf (&filename, "%s%s", directory, "messages.store");
372 
374  permission);
375 
377 
378  if (store->storage_messages)
379  {
381 
383  GNUNET_DISK_file_sync (save.storage);
384  }
385 
386 close_entries:
387  GNUNET_DISK_file_close (save.storage);
388 }
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_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 391 of file gnunet-service-messenger_message_store.c.

393 {
394  GNUNET_assert((store) && (hash));
395 
397  return GNUNET_YES;
398 
399  return GNUNET_CONTAINER_multihashmap_contains (store->entries, hash);
400 }

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

405 {
406  GNUNET_assert((store) && (hash));
407 
409 
410  if (message)
411  return message;
412 
413  if (!store->storage_messages)
414  return NULL;
415 
416  const struct GNUNET_MESSENGER_MessageEntry *entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash);
417 
418  if (!entry)
419  return NULL;
420 
422  return message;
423 
424  char *buffer = GNUNET_malloc(entry->length);
425 
426  if (!buffer)
427  return NULL;
428 
429  if ((GNUNET_DISK_file_read (store->storage_messages, buffer, entry->length) != entry->length) ||
431  goto free_buffer;
432 
434 
435  const int decoding = decode_message (message, entry->length, buffer, GNUNET_YES, NULL);
436 
437  struct GNUNET_HashCode check;
438  hash_message (message, entry->length, buffer, &check);
439 
440  if ((GNUNET_YES != decoding) || (GNUNET_CRYPTO_hash_cmp (hash, &check) != 0))
441  {
442  if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (store->entries, hash, entry))
443  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Corrupted entry could not be removed from store: %s\n",
444  GNUNET_h2s(hash));
445 
446  store->rewrite_entries = GNUNET_YES;
447 
448  goto free_message;
449  }
450 
451  if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (store->messages, hash, message,
453  goto free_buffer;
454 
455 free_message: destroy_message (message);
456  message = NULL;
457 
458 free_buffer:
459  GNUNET_free(buffer);
460 
461  return message;
462 }
#define GNUNET_log(kind,...)
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:201
int 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.
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.
int decode_message(struct GNUNET_MESSENGER_Message *message, uint16_t length, const char *buffer, int include_signature, uint16_t *padding)
Decodes a message from a given buffer of a maximal length in bytes.
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.
uint16_t get_message_kind_size(enum GNUNET_MESSENGER_MessageKind kind)
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_room_peer_status(), delete_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 465 of file gnunet-service-messenger_message_store.c.

468 {
469  if (deleted_only)
470  goto get_link;
471 
472  const struct GNUNET_MESSENGER_Message *message = get_store_message(store, hash);
473 
474  if (!message)
475  goto get_link;
476 
477  static struct GNUNET_MESSENGER_MessageLink link;
478 
479  GNUNET_memcpy(&(link.first), &(message->header.previous), sizeof(link.first));
480 
481  link.multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind? GNUNET_YES : GNUNET_NO;
482 
483  if (GNUNET_YES == link.multiple)
484  GNUNET_memcpy(&(link.second), &(message->body.merge.previous), sizeof(link.second));
485  else
486  GNUNET_memcpy(&(link.second), &(message->header.previous), sizeof(link.second));
487 
488  return &link;
489 
490 get_link:
491  return GNUNET_CONTAINER_multihashmap_get (store->links, hash);
492 }
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_MessageMerge::previous, GNUNET_MESSENGER_MessageHeader::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 495 of file gnunet-service-messenger_message_store.c.

498 {
499  GNUNET_assert((store) && (hash) && (message));
500 
501  return GNUNET_CONTAINER_multihashmap_put (store->messages, hash, message,
503 }

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

509 {
511 
512  GNUNET_memcpy(&(link->first), &(message->header.previous), sizeof(link->first));
513 
515 
516  if (GNUNET_YES == link->multiple)
517  GNUNET_memcpy(&(link->second), &(message->body.merge.previous), sizeof(link->second));
518  else
519  GNUNET_memcpy(&(link->second), &(message->header.previous), sizeof(link->second));
520 
521  if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(store->links, hash, link,
523  GNUNET_free(link);
524 }

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_MessageMerge::previous, GNUNET_MESSENGER_MessageHeader::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 527 of file gnunet-service-messenger_message_store.c.

529 {
530  GNUNET_assert((store) && (hash));
531 
532  const struct GNUNET_MESSENGER_MessageEntry *entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash);
533 
534  if (!entry)
535  goto clear_memory;
536 
537  const struct GNUNET_MESSENGER_Message *message = get_store_message(store, hash);
538 
539  if (message)
540  add_link (store, hash, message);
541 
542  if (!store->storage_messages)
543  goto clear_entry;
544 
546  return GNUNET_SYSERR;
547 
548  char *clear_buffer = GNUNET_malloc(entry->length);
549 
550  if (!clear_buffer)
551  return GNUNET_SYSERR;
552 
553  GNUNET_CRYPTO_zero_keys (clear_buffer, entry->length);
554 
555  if ((entry->length != GNUNET_DISK_file_write (store->storage_messages, clear_buffer, entry->length)) || (GNUNET_OK
557  {
558  GNUNET_free(clear_buffer);
559  return GNUNET_SYSERR;
560  }
561 
562  GNUNET_free(clear_buffer);
563 
564 clear_entry:
565  if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (store->entries, hash, entry))
566  store->rewrite_entries = GNUNET_YES;
567 
568 clear_memory:
570  return GNUNET_OK;
571 }
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: