GNUnet 0.29.1-6-gb66d952d5
 
Loading...
Searching...
No Matches
gnunet-service-messenger_message_store.h File Reference
#include "gnunet_util_lib.h"
Include dependency graph for gnunet-service-messenger_message_store.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  GNUNET_MESSENGER_MessageEntry
 
struct  GNUNET_MESSENGER_MessageLink
 
struct  GNUNET_MESSENGER_MessageStore
 

Functions

void init_message_store (struct GNUNET_MESSENGER_MessageStore *store, const char *directory)
 Initializes a message store as fully empty using a specific directory.
 
void clear_message_store (struct GNUNET_MESSENGER_MessageStore *store)
 Clears a message store, wipes its content and deallocates its memory.
 
void move_message_store (struct GNUNET_MESSENGER_MessageStore *store, const char *directory)
 Moves all storage from a message store from its current directory to a given directory.
 
void load_message_store (struct GNUNET_MESSENGER_MessageStore *store)
 Loads messages from its directory into a message store.
 
void save_message_store (struct GNUNET_MESSENGER_MessageStore *store)
 Saves messages from a message store into its directory.
 
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.
 
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.
 
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.
 
const struct GNUNET_HashCode * get_store_message_epoch (const struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
 Returns the epoch hash of a message from a message store matching a given hash.
 
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.
 
enum GNUNET_GenericReturnValue delete_store_message (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
 Deletes a message in the message store.
 
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.
 

Function Documentation

◆ init_message_store()

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

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

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

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

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

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

Referenced by create_srv_room().

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

◆ clear_message_store()

void clear_message_store ( struct GNUNET_MESSENGER_MessageStore *  store)

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

Parameters
[in,out]storeMessage store

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

111{
112 GNUNET_assert (store);
113
114 if (store->storage_messages)
115 {
117 store->storage_messages = NULL;
118 }
119
120 if (store->writing_task)
121 {
123 store->writing_task = NULL;
124 }
125
131 NULL);
135 NULL);
136
142
143 store->entries = NULL;
144 store->messages = NULL;
145 store->links = NULL;
146 store->discourses = NULL;
147 store->epochs = NULL;
148
149 if (store->directory)
150 {
151 GNUNET_free (store->directory);
152 store->directory = NULL;
153 }
154}
static enum GNUNET_GenericReturnValue iterate_destroy_hashs(void *cls, const struct GNUNET_HashCode *key, void *value)
static enum GNUNET_GenericReturnValue iterate_destroy_entries(void *cls, const struct GNUNET_HashCode *key, void *value)
static enum GNUNET_GenericReturnValue iterate_destroy_messages(void *cls, const struct GNUNET_HashCode *key, void *value)
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition disk.c:1386
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.
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986

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

Referenced by destroy_srv_room().

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

◆ move_message_store()

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

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

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

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

160{
161 GNUNET_assert ((store) && (directory));
162
163 if (store->directory)
164 {
165 if (0 == strcmp (store->directory, directory))
166 return;
167
169 {
171 "Moving message store failed because directory exists already! (%s)\n",
172 directory);
173 return;
174 }
175
176 if (0 != rename (store->directory, directory))
177 {
179 "Moving message store failed! (%s -> %s)\n",
180 store->directory, directory);
181 return;
182 }
183
184 GNUNET_free (store->directory);
185 }
186
187 store->directory = GNUNET_strdup (directory);
188}
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition disk.c:466
#define GNUNET_log(kind,...)
@ GNUNET_YES
@ GNUNET_ERROR_TYPE_ERROR

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

Referenced by load_srv_room(), and save_srv_room().

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

◆ load_message_store()

void load_message_store ( struct GNUNET_MESSENGER_MessageStore *  store)

Loads messages from its directory into a message store.

Parameters
[out]storeMessage store

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

431{
432 enum GNUNET_DISK_AccessPermissions permission;
433 char *filename;
434
435 GNUNET_assert (store);
436
437 if (! store->directory)
438 return;
439
441
442 if (store->storage_messages)
444
446 "%s%s", store->directory, "messages.store");
447
451 permission);
452 else
453 store->storage_messages = NULL;
454
456
457 if (! store->storage_messages)
458 return;
459
461 "%s%s", store->directory, "entries.store");
462
465
468 "%s%s", store->directory, "links.store");
469
472
475 "%s%s", store->directory, "epochs.store");
476
479
481}
static char * filename
static void load_message_store_entries(struct GNUNET_MESSENGER_MessageStore *store, const char *filename)
static void load_message_store_links(struct GNUNET_MESSENGER_MessageStore *store, const char *filename)
static void load_message_store_epochs(struct GNUNET_MESSENGER_MessageStore *store, const char *filename)
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:1308
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:557
GNUNET_DISK_AccessPermissions
File access permissions, UNIX-style.
@ GNUNET_DISK_OPEN_READWRITE
Open the file for both reading and writing.
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.

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

Referenced by load_srv_room().

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

◆ save_message_store()

void save_message_store ( struct GNUNET_MESSENGER_MessageStore *  store)

Saves messages from a message store into its directory.

Parameters
[in]storeMessage store

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

655{
657 enum GNUNET_DISK_AccessPermissions permission;
658 char *filename;
659
661
662 if (store->writing_task)
663 {
665 store->writing_task = NULL;
666 }
667
668 if (! store->directory)
669 return;
670
672
674 "%s%s", store->directory, "epochs.store");
675
676 save.store = store;
678 | GNUNET_DISK_OPEN_CREATE, permission);
679
681
682 if (! save.storage)
683 {
685 "No access to local storage of message epochs!\n");
686 goto save_links;
687 }
688
689 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
691 goto close_epochs;
692
694 &save);
695
696close_epochs:
698
699save_links:
701 goto save_entries;
702
704 "%s%s", store->directory, "links.store");
705
706 save.store = store;
708 | GNUNET_DISK_OPEN_CREATE, permission);
709
711
712 if (! save.storage)
713 {
715 "No access to local storage of message links!\n");
716 goto save_entries;
717 }
718
719 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
721 goto close_links;
722
724 &save);
726
727close_links:
729
730save_entries:
732 "%s%s", store->directory, "entries.store");
733
734 save.store = store;
736 | GNUNET_DISK_OPEN_CREATE, permission);
737
739
740 if (! save.storage)
741 {
743 "No access to local storage of message entries!\n");
744 return;
745 }
746
748 {
749 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
751 goto close_entries;
752
754 &save);
756 }
757 else if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
759 goto close_entries;
760
763
765 "%s%s", store->directory, "messages.store");
766
770 permission);
771
773
775 {
778
780 GNUNET_DISK_file_sync (save.storage);
781 }
782
783close_entries:
785 save.storage = NULL;
786}
static enum GNUNET_GenericReturnValue iterate_save_entries(void *cls, const struct GNUNET_HashCode *key, void *value)
static enum GNUNET_GenericReturnValue iterate_save_links(void *cls, const struct GNUNET_HashCode *key, void *value)
static enum GNUNET_GenericReturnValue iterate_save_messages(void *cls, const struct GNUNET_HashCode *key, void *value)
static enum GNUNET_GenericReturnValue iterate_save_epochs(void *cls, const struct GNUNET_HashCode *key, void *value)
static void save()
Write persistent statistics to disk.
off_t GNUNET_DISK_file_seek(const struct GNUNET_DISK_FileHandle *h, off_t offset, enum GNUNET_DISK_Seek whence)
Move the read/write pointer in a file.
Definition disk.c:219
enum GNUNET_GenericReturnValue GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
Definition disk.c:1507
@ 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).
@ GNUNET_DISK_SEEK_END
Seek an absolute position from the end of the file.
@ GNUNET_SYSERR

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

Referenced by save_srv_room(), and task_save_messages().

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

◆ contains_store_message()

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

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

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

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

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

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

792{
793 GNUNET_assert ((store) && (hash));
794
796 hash))
797 return GNUNET_YES;
798
800 hash))
801 return GNUNET_YES;
802
804}
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).

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

810{
811 struct GNUNET_MESSENGER_Message *message;
812 const struct GNUNET_MESSENGER_MessageEntry *entry;
813 enum GNUNET_GenericReturnValue decoding;
814 struct GNUNET_HashCode check;
815 char *buffer;
816
817 GNUNET_assert ((store) && (hash));
818
819 if (GNUNET_is_zero (hash))
820 return NULL;
821
822 message = GNUNET_CONTAINER_multihashmap_get (store->messages, hash);
823
824 if (message)
825 return message;
826
827 message = GNUNET_CONTAINER_multihashmap_get (store->discourses, hash);
828
829 if (message)
830 return message;
831
832 if (! store->storage_messages)
833 {
835 "Local storage of messages is unavailable: %s\n",
836 GNUNET_h2s (hash));
837 return NULL;
838 }
839
840 entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash);
841
842 if (! entry)
843 {
845 "No entry in storage for message found: %s\n",
846 GNUNET_h2s (hash));
847 return NULL;
848 }
849
850 if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages,
851 entry->offset,
853 {
855 "Offset for message in local storage invalid: %s\n",
856 GNUNET_h2s (hash));
857 return NULL;
858 }
859
860 buffer = GNUNET_malloc (entry->length);
861
862 if (! buffer)
863 {
865 "Allocation for message data buffer failed: %s\n",
866 GNUNET_h2s (hash));
867 return NULL;
868 }
869
870 if ((GNUNET_DISK_file_read (store->storage_messages, buffer, entry->length) !=
871 entry->length) ||
873 GNUNET_YES)))
874 {
876 "Reading message from local storage failed: %s\n",
877 GNUNET_h2s (hash));
878 goto free_buffer;
879 }
880
882 decoding = decode_message (message, entry->length, buffer,
883 GNUNET_YES, NULL);
884
885 hash_message (message, entry->length, buffer, &check);
886
887 if ((GNUNET_YES != decoding) || (GNUNET_CRYPTO_hash_cmp (hash, &check) != 0))
888 {
890 "Decoding message failed or checksum mismatched: %s\n",
891 GNUNET_h2s (hash));
892
894 hash, entry))
896 "Corrupted entry could not be removed from store: %s\n",
897 GNUNET_h2s (hash));
898
900 goto free_message;
901 }
902
904 store->messages, hash, message,
906 goto free_buffer;
907
908free_message:
909 destroy_message (message);
910 message = NULL;
911
912free_buffer:
913 GNUNET_free (buffer);
914 return message;
915}
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:704
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.
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.
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_is_zero(a)
Check that memory in a is all zeros.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_malloc(size)
Wrapper around malloc.
@ 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.
void destroy_message(struct GNUNET_MESSENGER_Message *message)
Destroys a message and frees its memory fully.
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 maximum length in bytes.
A 512-bit hashcode.

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

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

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

◆ get_store_message_link()

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

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

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

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

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

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

922{
923 const struct GNUNET_MESSENGER_Message *message;
924
925 if (GNUNET_is_zero (hash))
926 return NULL;
927
928 if (GNUNET_YES == deleted_only)
929 goto get_link;
930
931 message = get_store_message (store, hash);
932
933 if (message)
934 {
935 static struct GNUNET_MESSENGER_MessageLink link;
936
937 GNUNET_memcpy (&(link.first), &(message->header.previous),
938 sizeof(link.first));
939
940 link.multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind?
942
943 if (GNUNET_YES == link.multiple)
944 GNUNET_memcpy (&(link.second), &(message->body.merge.previous),
945 sizeof(link.second));
946 else
947 GNUNET_memcpy (&(link.second), &(message->header.previous),
948 sizeof(link.second));
949
950 return &link;
951 }
952
953get_link:
954 return GNUNET_CONTAINER_multihashmap_get (store->links, hash);
955}
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.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_MESSENGER_KIND_MERGE
The merge kind.
struct GNUNET_MESSENGER_MessageMerge merge
struct GNUNET_HashCode previous
The hash of the previous message from the senders perspective.
enum GNUNET_MESSENGER_MessageKind kind
The kind of the message.
struct GNUNET_HashCode previous
The hash of a second previous message.
struct GNUNET_MESSENGER_MessageHeader header
Header.
struct GNUNET_MESSENGER_MessageBody body
Body.

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

Referenced by check_member_session_completion(), and request_room_message_step().

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

◆ get_store_message_epoch()

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

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

If no matching message is found, NULL gets returned.

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

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

961{
962 struct GNUNET_HashCode *epoch;
963
964 GNUNET_assert ((store) && (hash));
965
966 epoch = GNUNET_CONTAINER_multihashmap_get (store->epochs, hash);
967
968 if (! epoch)
969 return hash;
970
971 return epoch;
972}

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

Referenced by callback_found_message(), handle_room_messages(), iterate_srv_handle_sync_finished(), notify_about_members(), put_store_message(), and sign_srv_room_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 1056 of file gnunet-service-messenger_message_store.c.

1059{
1060 struct GNUNET_HashCode *epoch;
1063
1064 GNUNET_assert ((store) && (hash) && (message));
1065
1066 if (GNUNET_is_zero (hash))
1067 return GNUNET_SYSERR;
1068
1069 epoch = GNUNET_CONTAINER_multihashmap_get (store->epochs, hash);
1070
1071 if (epoch)
1072 goto reverse_epoch;
1073
1074 epoch = GNUNET_new (struct GNUNET_HashCode);
1075
1076 if (! epoch)
1077 goto skip_epoch;
1078
1079 switch (message->header.kind)
1080 {
1083 GNUNET_memcpy (epoch, hash, sizeof (struct GNUNET_HashCode));
1084 break;
1086 {
1087 const struct GNUNET_HashCode *epoch0;
1088 const struct GNUNET_HashCode *epoch1;
1089
1090 epoch0 = &(message->body.merge.epochs[0]);
1091 epoch1 = &(message->body.merge.epochs[1]);
1092
1093 if (0 == GNUNET_CRYPTO_hash_cmp (epoch0, epoch1))
1094 GNUNET_memcpy (epoch, epoch0, sizeof (struct GNUNET_HashCode));
1095 else
1096 GNUNET_memcpy (epoch, hash, sizeof (struct GNUNET_HashCode));
1097
1098 break;
1099 }
1100 default:
1102 epoch,
1103 get_store_message_epoch (store, &(message->header.previous)),
1104 sizeof (struct GNUNET_HashCode));
1105 break;
1106 }
1107
1109 store->epochs, hash, epoch,
1111 {
1112 GNUNET_free (epoch);
1113 goto skip_epoch;
1114 }
1115
1116reverse_epoch:
1117 switch (message->header.kind)
1118 {
1121 store,
1122 &(message->header.previous),
1123 &(message->body.join.epoch));
1124 break;
1127 store,
1128 &(message->header.previous),
1129 &(message->body.leave.epoch));
1130 break;
1133 store,
1134 &(message->header.previous),
1135 &(message->body.merge.epochs[0]));
1137 store,
1138 &(message->body.merge.previous),
1139 &(message->body.merge.epochs[1]));
1140 break;
1141 default:
1143 store,
1144 &(message->header.previous),
1145 epoch);
1146 break;
1147 }
1148
1149skip_epoch:
1150 map = store->messages;
1151
1152 if (get_message_discourse (message))
1153 map = store->discourses;
1154
1156 {
1158 "Message has already been stored! (%s)\n",
1159 GNUNET_h2s (hash));
1160 return GNUNET_SYSERR;
1161 }
1162
1164 map, hash, message,
1166
1167 if ((GNUNET_OK != result) || (map == store->discourses))
1168 return result;
1169
1170 if (! store->writing_task)
1174 store);
1175
1176 return result;
1177}
static int result
Global testing status.
static void task_save_messages(void *cls)
const struct GNUNET_HashCode * get_store_message_epoch(const struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
Returns the epoch hash of a message from a message store matching a given hash.
static void put_store_message_epoch(struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash, const struct GNUNET_HashCode *epoch)
@ GNUNET_SCHEDULER_PRIORITY_BACKGROUND
Run as background job (higher than idle, lower than default).
#define GNUNET_new(type)
Allocate a struct or union of the given type.
@ GNUNET_MESSENGER_KIND_LEAVE
The leave kind.
@ GNUNET_MESSENGER_KIND_JOIN
The join kind.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_with_priority(enum GNUNET_SCHEDULER_Priority prio, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified priority.
Definition scheduler.c:1237
const struct GNUNET_ShortHashCode * get_message_discourse(const struct GNUNET_MESSENGER_Message *message)
Returns the discourse hash of a message depending on its kind.
static struct GNUNET_CONTAINER_MultiPeerMap * map
Peermap of PeerIdentities to "struct PeerEntry" (for fast lookup).
Definition peer.c:63
Internal representation of the hash map.
struct GNUNET_MESSENGER_MessageLeave leave
struct GNUNET_MESSENGER_MessageJoin join
struct GNUNET_HashCode epoch
The previous epoch the message was sent from.
struct GNUNET_HashCode epoch
The previous epoch the message was sent from.
struct GNUNET_HashCode epochs[2]
The previous epochs the message was sent from.

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

Referenced by update_room_message().

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

◆ delete_store_message()

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

Deletes a message in the message store.

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

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

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

1183{
1184 const struct GNUNET_MESSENGER_MessageEntry *entry;
1185 const struct GNUNET_MESSENGER_Message *message;
1186
1187 GNUNET_assert ((store) && (hash));
1188
1189 entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash);
1190
1191 if (! entry)
1192 goto clear_memory;
1193
1194 message = get_store_message (store, hash);
1195
1196 if (message)
1197 {
1198 if (GNUNET_YES == is_epoch_message (message))
1199 {
1201 "Deletion of message is not allowed! (%s)\n",
1202 GNUNET_h2s (hash));
1203 return GNUNET_SYSERR;
1204 }
1205
1206 add_link (store, hash, message);
1207 }
1208
1209 if (! store->storage_messages)
1210 goto clear_entry;
1211
1212 if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages,
1213 entry->offset,
1215 return GNUNET_SYSERR;
1216
1217 {
1219 char *clear_buffer;
1220
1221 clear_buffer = GNUNET_malloc (entry->length);
1222
1223 if (! clear_buffer)
1224 return GNUNET_SYSERR;
1225
1226 GNUNET_CRYPTO_zero_keys (clear_buffer, entry->length);
1227
1228 if ((entry->length != GNUNET_DISK_file_write (store->storage_messages,
1229 clear_buffer, entry->length))
1230 ||
1233 else
1234 result = GNUNET_OK;
1235
1236 GNUNET_free (clear_buffer);
1237
1238 if (GNUNET_OK != result)
1239 return result;
1240 }
1241
1242clear_entry:
1244 entry))
1245 store->rewrite_entries = GNUNET_YES;
1246
1247clear_memory:
1251 return GNUNET_OK;
1252}
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.
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:745
int GNUNET_CONTAINER_multihashmap_remove_all(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Remove all entries for the given key from the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
enum GNUNET_GenericReturnValue is_epoch_message(const struct GNUNET_MESSENGER_Message *message)
Returns whether a certain kind of message from storage contains some specific details that might be r...

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

Referenced by callback_operation().

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

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

1303{
1306
1307 GNUNET_assert ((store) && (discourse));
1308
1310
1311 cleanup.list = &list;
1312 cleanup.timestamp = timestamp;
1313
1314 GNUNET_memcpy (&(cleanup.discourse), discourse,
1315 sizeof (struct GNUNET_ShortHashCode));
1316
1319 &cleanup);
1320
1321 {
1322 struct GNUNET_MESSENGER_ListMessage *element;
1323 for (element = list.head; element; element = element->next)
1325 &(element->hash)))
1327 store->epochs, &(element->hash));
1328 }
1329
1331}
static int list
Set if we should print a list of currently running services.
Definition gnunet-arm.c:68
static uint64_t timestamp(void)
Get current timestamp.
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)
static void cleanup()
Cleanup task.
struct GNUNET_MESSENGER_ListMessage * next
A 256-bit hashcode.

References cleanup(), clear_list_messages(), GNUNET_MESSENGER_CleanupDiscourseMessages::discourse, GNUNET_MESSENGER_MessageStore::discourses, GNUNET_MESSENGER_MessageStore::epochs, 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: