GNUnet 0.28.0-dev.3-20-gf1136b0b8
 
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_Messageget_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_MessageLinkget_store_message_link (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash, enum GNUNET_GenericReturnValue deleted_only)
 Returns the message link from a message store matching a given hash.
 
const struct GNUNET_HashCodeget_store_message_epoch (const struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
 Returns the epoch hash of a message from a message store matching a given hash.
 
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 649 of file gnunet-service-messenger_message_store.c.

650{
652 enum GNUNET_DISK_AccessPermissions permission;
653 char *filename;
654
656
657 if (! store->directory)
658 return;
659
661
663 "%s%s", store->directory, "epochs.store");
664
665 save.store = store;
667 | GNUNET_DISK_OPEN_CREATE, permission);
668
670
671 if (! save.storage)
672 {
674 "No access to local storage of message epochs!\n");
675 goto save_links;
676 }
677
678 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
680 goto close_epochs;
681
683 &save);
684
685close_epochs:
687
688save_links:
690 goto save_entries;
691
693 "%s%s", store->directory, "links.store");
694
695 save.store = store;
697 | GNUNET_DISK_OPEN_CREATE, permission);
698
700
701 if (! save.storage)
702 {
704 "No access to local storage of message links!\n");
705 goto save_entries;
706 }
707
708 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
710 goto close_links;
711
713 &save);
715
716close_links:
718
719save_entries:
721 "%s%s", store->directory, "entries.store");
722
723 save.store = store;
725 | GNUNET_DISK_OPEN_CREATE, permission);
726
728
729 if (! save.storage)
730 {
732 "No access to local storage of message entries!\n");
733 return;
734 }
735
737 {
738 if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
740 goto close_entries;
741
743 &save);
745 }
746 else if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0,
748 goto close_entries;
749
752
754 "%s%s", store->directory, "messages.store");
755
759 permission);
760
762
764 {
767
769 GNUNET_DISK_file_sync (save.storage);
770 }
771
772close_entries:
774 save.storage = NULL;
775}
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_SYSERR, GNUNET_YES, iterate_save_entries(), iterate_save_epochs(), iterate_save_links(), iterate_save_messages(), GNUNET_MESSENGER_MessageStore::links, GNUNET_MESSENGER_MessageStore::messages, GNUNET_MESSENGER_MessageStore::rewrite_entries, save(), GNUNET_MESSENGER_MessageStore::storage_messages, GNUNET_MESSENGER_ClosureMessageSave::store, and GNUNET_MESSENGER_MessageStore::write_links.

Referenced by save_srv_room(), and task_save_messages().

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

◆ contains_store_message()

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

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

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

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

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

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

781{
782 GNUNET_assert ((store) && (hash));
783
785 hash))
786 return GNUNET_YES;
787
789 hash))
790 return GNUNET_YES;
791
793}
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 797 of file gnunet-service-messenger_message_store.c.

799{
800 struct GNUNET_MESSENGER_Message *message;
801 const struct GNUNET_MESSENGER_MessageEntry *entry;
802 enum GNUNET_GenericReturnValue decoding;
803 struct GNUNET_HashCode check;
804 char *buffer;
805
806 GNUNET_assert ((store) && (hash));
807
808 if (GNUNET_is_zero (hash))
809 return NULL;
810
811 message = GNUNET_CONTAINER_multihashmap_get (store->messages, hash);
812
813 if (message)
814 return message;
815
816 message = GNUNET_CONTAINER_multihashmap_get (store->discourses, hash);
817
818 if (message)
819 return message;
820
821 if (! store->storage_messages)
822 {
824 "Local storage of messages is unavailable: %s\n",
825 GNUNET_h2s (hash));
826 return NULL;
827 }
828
829 entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash);
830
831 if (! entry)
832 {
834 "No entry in storage for message found: %s\n",
835 GNUNET_h2s (hash));
836 return NULL;
837 }
838
839 if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages,
840 entry->offset,
842 {
844 "Offset for message in local storage invalid: %s\n",
845 GNUNET_h2s (hash));
846 return NULL;
847 }
848
849 buffer = GNUNET_malloc (entry->length);
850
851 if (! buffer)
852 {
854 "Allocation for message data buffer failed: %s\n",
855 GNUNET_h2s (hash));
856 return NULL;
857 }
858
859 if ((GNUNET_DISK_file_read (store->storage_messages, buffer, entry->length) !=
860 entry->length) ||
862 GNUNET_YES)))
863 {
865 "Reading message from local storage failed: %s\n",
866 GNUNET_h2s (hash));
867 goto free_buffer;
868 }
869
871 decoding = decode_message (message, entry->length, buffer,
872 GNUNET_YES, NULL);
873
874 hash_message (message, entry->length, buffer, &check);
875
876 if ((GNUNET_YES != decoding) || (GNUNET_CRYPTO_hash_cmp (hash, &check) != 0))
877 {
879 "Decoding message failed or checksum mismatched: %s\n",
880 GNUNET_h2s (hash));
881
883 hash, entry))
885 "Corrupted entry could not be removed from store: %s\n",
886 GNUNET_h2s (hash));
887
889 goto free_message;
890 }
891
893 store->messages, hash, message,
895 goto free_buffer;
896
897free_message:
898 destroy_message (message);
899 message = NULL;
900
901free_buffer:
902 GNUNET_free (buffer);
903 return message;
904}
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 908 of file gnunet-service-messenger_message_store.c.

911{
912 const struct GNUNET_MESSENGER_Message *message;
913
914 if (GNUNET_is_zero (hash))
915 return NULL;
916
917 if (GNUNET_YES == deleted_only)
918 goto get_link;
919
920 message = get_store_message (store, hash);
921
922 if (message)
923 {
924 static struct GNUNET_MESSENGER_MessageLink link;
925
926 GNUNET_memcpy (&(link.first), &(message->header.previous),
927 sizeof(link.first));
928
929 link.multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind?
931
932 if (GNUNET_YES == link.multiple)
933 GNUNET_memcpy (&(link.second), &(message->body.merge.previous),
934 sizeof(link.second));
935 else
936 GNUNET_memcpy (&(link.second), &(message->header.previous),
937 sizeof(link.second));
938
939 return &link;
940 }
941
942get_link:
943 return GNUNET_CONTAINER_multihashmap_get (store->links, hash);
944}
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 948 of file gnunet-service-messenger_message_store.c.

950{
951 struct GNUNET_HashCode *epoch;
952
953 GNUNET_assert ((store) && (hash));
954
955 epoch = GNUNET_CONTAINER_multihashmap_get (store->epochs, hash);
956
957 if (! epoch)
958 return hash;
959
960 return epoch;
961}

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

1048{
1049 struct GNUNET_HashCode *epoch;
1052
1053 GNUNET_assert ((store) && (hash) && (message));
1054
1055 if (GNUNET_is_zero (hash))
1056 return GNUNET_SYSERR;
1057
1058 epoch = GNUNET_CONTAINER_multihashmap_get (store->epochs, hash);
1059
1060 if (epoch)
1061 goto reverse_epoch;
1062
1063 epoch = GNUNET_new (struct GNUNET_HashCode);
1064
1065 if (! epoch)
1066 goto skip_epoch;
1067
1068 switch (message->header.kind)
1069 {
1072 GNUNET_memcpy (epoch, hash, sizeof (struct GNUNET_HashCode));
1073 break;
1075 {
1076 const struct GNUNET_HashCode *epoch0;
1077 const struct GNUNET_HashCode *epoch1;
1078
1079 epoch0 = &(message->body.merge.epochs[0]);
1080 epoch1 = &(message->body.merge.epochs[1]);
1081
1082 if (0 == GNUNET_CRYPTO_hash_cmp (epoch0, epoch1))
1083 GNUNET_memcpy (epoch, epoch0, sizeof (struct GNUNET_HashCode));
1084 else
1085 GNUNET_memcpy (epoch, hash, sizeof (struct GNUNET_HashCode));
1086
1087 break;
1088 }
1089 default:
1091 epoch,
1092 get_store_message_epoch (store, &(message->header.previous)),
1093 sizeof (struct GNUNET_HashCode));
1094 break;
1095 }
1096
1098 store->epochs, hash, epoch,
1100 {
1101 GNUNET_free (epoch);
1102 goto skip_epoch;
1103 }
1104
1105reverse_epoch:
1106 switch (message->header.kind)
1107 {
1110 store,
1111 &(message->header.previous),
1112 &(message->body.join.epoch));
1113 break;
1116 store,
1117 &(message->header.previous),
1118 &(message->body.leave.epoch));
1119 break;
1122 store,
1123 &(message->header.previous),
1124 &(message->body.merge.epochs[0]));
1126 store,
1127 &(message->body.merge.previous),
1128 &(message->body.merge.epochs[1]));
1129 break;
1130 default:
1132 store,
1133 &(message->header.previous),
1134 epoch);
1135 break;
1136 }
1137
1138skip_epoch:
1139 map = store->messages;
1140
1141 if (get_message_discourse (message))
1142 map = store->discourses;
1143
1145 {
1147 "Message has already been stored! (%s)\n",
1148 GNUNET_h2s (hash));
1149 return GNUNET_SYSERR;
1150 }
1151
1153 map, hash, message,
1155
1156 if ((GNUNET_OK != result) || (map == store->discourses))
1157 return result;
1158
1159 if (! store->writing_task)
1163 store);
1164
1165 return result;
1166}
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 1170 of file gnunet-service-messenger_message_store.c.

1172{
1173 const struct GNUNET_MESSENGER_MessageEntry *entry;
1174 const struct GNUNET_MESSENGER_Message *message;
1175
1176 GNUNET_assert ((store) && (hash));
1177
1178 entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash);
1179
1180 if (! entry)
1181 goto clear_memory;
1182
1183 message = get_store_message (store, hash);
1184
1185 if (message)
1186 {
1187 if (GNUNET_YES == is_epoch_message (message))
1188 {
1190 "Deletion of message is not allowed! (%s)\n",
1191 GNUNET_h2s (hash));
1192 return GNUNET_SYSERR;
1193 }
1194
1195 add_link (store, hash, message);
1196 }
1197
1198 if (! store->storage_messages)
1199 goto clear_entry;
1200
1201 if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages,
1202 entry->offset,
1204 return GNUNET_SYSERR;
1205
1206 {
1208 char *clear_buffer;
1209
1210 clear_buffer = GNUNET_malloc (entry->length);
1211
1212 if (! clear_buffer)
1213 return GNUNET_SYSERR;
1214
1215 GNUNET_CRYPTO_zero_keys (clear_buffer, entry->length);
1216
1217 if ((entry->length != GNUNET_DISK_file_write (store->storage_messages,
1218 clear_buffer, entry->length))
1219 ||
1222 else
1223 result = GNUNET_OK;
1224
1225 GNUNET_free (clear_buffer);
1226
1227 if (GNUNET_OK != result)
1228 return result;
1229 }
1230
1231clear_entry:
1233 entry))
1234 store->rewrite_entries = GNUNET_YES;
1235
1236clear_memory:
1240 return GNUNET_OK;
1241}
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 1286 of file gnunet-service-messenger_message_store.c.

1292{
1295
1296 GNUNET_assert ((store) && (discourse));
1297
1299
1300 cleanup.list = &list;
1301 cleanup.timestamp = timestamp;
1302
1303 GNUNET_memcpy (&(cleanup.discourse), discourse,
1304 sizeof (struct GNUNET_ShortHashCode));
1305
1308 &cleanup);
1309
1310 {
1311 struct GNUNET_MESSENGER_ListMessage *element;
1312 for (element = list.head; element; element = element->next)
1314 store->discourses,
1315 &(element->hash));
1316 }
1317
1319}
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_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: