GNUnet  0.11.x
gnunet-service-messenger_member_store.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2020--2021 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
27 
31 
32 void
34  struct GNUNET_MESSENGER_SrvRoom *room)
35 {
36  GNUNET_assert ((store) && (room));
37 
38  store->room = room;
40 }
41 
42 static int
44  const struct GNUNET_ShortHashCode *key,
45  void *value)
46 {
47  struct GNUNET_MESSENGER_Member *member = value;
48  destroy_member(member);
49  return GNUNET_YES;
50 }
51 
52 void
54 {
55  GNUNET_assert ((store) && (store->members));
56 
59 }
60 
61 
64 {
65  GNUNET_assert ((store) && (store->room));
66 
67  struct GNUNET_MESSENGER_SrvRoom *room = store->room;
68 
69  return get_service_contact_store(room->service);
70 }
71 
72 const struct GNUNET_HashCode*
74 {
75  GNUNET_assert (store);
76 
77  return get_room_key((const struct GNUNET_MESSENGER_SrvRoom*) store->room);
78 }
79 
80 static int
82  const char *filename)
83 {
84  struct GNUNET_MESSENGER_MemberStore *store = cls;
85 
87  {
88  char *directory;
89 
90  GNUNET_asprintf (&directory, "%s%c", filename, DIR_SEPARATOR);
91 
92  load_member(store, directory);
93 
94  GNUNET_free(directory);
95  }
96 
97  return GNUNET_OK;
98 }
99 
100 static int
102  const struct GNUNET_ShortHashCode *id,
103  void *value)
104 {
105  const char *sync_dir = cls;
106 
107  struct GNUNET_MESSENGER_Member *member = value;
108 
109  if (!member)
110  return GNUNET_YES;
111 
112  char *member_dir;
113  GNUNET_asprintf (&member_dir, "%s%s%c", sync_dir, GNUNET_sh2s(id), DIR_SEPARATOR);
114 
115  if (GNUNET_YES == GNUNET_DISK_directory_test (member_dir, GNUNET_YES))
116  load_member_next_sessions (member, member_dir);
117 
118  GNUNET_free(member_dir);
119  return GNUNET_YES;
120 }
121 
122 static int
124  const struct GNUNET_ShortHashCode *id,
125  void *value)
126 {
127  struct GNUNET_MESSENGER_Member *member = value;
128 
129  if (!member)
130  return GNUNET_YES;
131 
132  sync_member_contacts (member);
133  return GNUNET_YES;
134 }
135 
136 void
138  const char *directory)
139 {
140  GNUNET_assert ((store) && (directory));
141 
142  char *scan_dir;
143  GNUNET_asprintf (&scan_dir, "%s%s%c", directory, "members", DIR_SEPARATOR);
144 
147 
150 
152 }
153 
154 static int
156  const struct GNUNET_ShortHashCode *id,
157  void *value)
158 {
159  const char *save_dir = cls;
160 
161  struct GNUNET_MESSENGER_Member *member = value;
162 
163  if (!member)
164  return GNUNET_YES;
165 
166  char *member_dir;
167  GNUNET_asprintf (&member_dir, "%s%s%c", save_dir, GNUNET_sh2s(id), DIR_SEPARATOR);
168 
169  if ((GNUNET_YES == GNUNET_DISK_directory_test (member_dir, GNUNET_NO)) ||
170  (GNUNET_OK == GNUNET_DISK_directory_create (member_dir)))
171  save_member(member, member_dir);
172 
173  GNUNET_free(member_dir);
174  return GNUNET_YES;
175 }
176 
177 void
179  const char *directory)
180 {
181  GNUNET_assert ((store) && (directory));
182 
183  char* save_dir;
184  GNUNET_asprintf (&save_dir, "%s%s%c", directory, "members", DIR_SEPARATOR);
185 
186  if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) ||
187  (GNUNET_OK == GNUNET_DISK_directory_create (save_dir)))
189 
190  GNUNET_free(save_dir);
191 }
192 
195  const struct GNUNET_ShortHashCode *id)
196 {
197  GNUNET_assert ((store) && (store->members) && (id));
198 
200 }
201 
204  const struct GNUNET_MESSENGER_Message *message)
205 {
206  if ((GNUNET_MESSENGER_KIND_INFO == message->header.kind) ||
207  (GNUNET_MESSENGER_KIND_JOIN == message->header.kind))
208  return add_store_member(store, &(message->header.sender_id));
209  else
210  return get_store_member(store, &(message->header.sender_id));
211 }
212 
215  const struct GNUNET_ShortHashCode *id)
216 {
217  GNUNET_assert ((store) && (store->members));
218 
219  struct GNUNET_MESSENGER_Member *member = id? get_store_member(store, id) : NULL;
220 
221  if (member)
222  return member;
223 
224  member = create_member(store, id);
225 
226  if (!member)
227  return NULL;
228 
231  {
232  destroy_member(member);
233  return NULL;
234  }
235 
236  return member;
237 }
238 
241  void *cls;
242 };
243 
244 static int
246  const struct GNUNET_ShortHashCode *key,
247  void *value)
248 {
250  struct GNUNET_MESSENGER_Member *member = value;
251 
252  return iterate_member_sessions(member, iterate->it, iterate->cls);
253 }
254 
255 int
258  void* cls)
259 {
260  GNUNET_assert ((store) && (store->members) && (it));
261 
263 
264  iterate.it = it;
265  iterate.cls = cls;
266 
268 }
struct GNUNET_HashCode key
The key used in the DHT.
static char * filename
static char * value
Value of the record to add/remove.
struct GNUNET_MESSENGER_Member * create_member(struct GNUNET_MESSENGER_MemberStore *store, const struct GNUNET_ShortHashCode *id)
Creates and allocates a new member of a room with an optionally defined or random id.
void save_member(struct GNUNET_MESSENGER_Member *member, const char *directory)
Saves data from a member into a directory which can be load to restore the member completely.
void destroy_member(struct GNUNET_MESSENGER_Member *member)
Destroys a member and frees its memory fully.
void load_member_next_sessions(const struct GNUNET_MESSENGER_Member *member, const char *directory)
Loads data about next sessions from a directory into an empty loaded member which does not contain a ...
void sync_member_contacts(struct GNUNET_MESSENGER_Member *member)
Synchronizes contacts between all sessions from a given member and other sessions which are linked to...
int iterate_member_sessions(struct GNUNET_MESSENGER_Member *member, GNUNET_MESSENGER_MemberIteratorCallback it, void *cls)
Iterate through all member sessions currently connected to a given member and call the provided itera...
const struct GNUNET_ShortHashCode * get_member_id(const struct GNUNET_MESSENGER_Member *member)
Returns the current id of a given member.
void load_member(struct GNUNET_MESSENGER_MemberStore *store, const char *directory)
Loads data from a directory into a new allocated and created member of a store if the required inform...
GNUnet MESSENGER service.
struct GNUNET_MESSENGER_Member * get_store_member_of(struct GNUNET_MESSENGER_MemberStore *store, const struct GNUNET_MESSENGER_Message *message)
Returns the member of a store using a sender id of a given message.
static int iterate_sync_member_contacts(void *cls, const struct GNUNET_ShortHashCode *id, void *value)
int iterate_store_members(struct GNUNET_MESSENGER_MemberStore *store, GNUNET_MESSENGER_MemberIteratorCallback it, void *cls)
Iterate through all member sessions currently connected to the members of the given member store and ...
void save_member_store(struct GNUNET_MESSENGER_MemberStore *store, const char *directory)
Saves members from a member store into a directory.
void load_member_store(struct GNUNET_MESSENGER_MemberStore *store, const char *directory)
Loads members from a directory into a member store.
struct GNUNET_MESSENGER_Member * get_store_member(const struct GNUNET_MESSENGER_MemberStore *store, const struct GNUNET_ShortHashCode *id)
Returns the member in a store identified by a given id.
static int iterate_destroy_members(void *cls, const struct GNUNET_ShortHashCode *key, void *value)
static int iterate_load_next_member_sessions(void *cls, const struct GNUNET_ShortHashCode *id, void *value)
const struct GNUNET_HashCode * get_member_store_key(const struct GNUNET_MESSENGER_MemberStore *store)
Returns the shared secret you need to access a room of the store.
static int iterate_store_members_it(void *cls, const struct GNUNET_ShortHashCode *key, void *value)
struct GNUNET_MESSENGER_ContactStore * get_member_contact_store(struct GNUNET_MESSENGER_MemberStore *store)
Returns the used contact store of a given member store.
static int iterate_save_members(void *cls, const struct GNUNET_ShortHashCode *id, void *value)
void init_member_store(struct GNUNET_MESSENGER_MemberStore *store, struct GNUNET_MESSENGER_SrvRoom *room)
Initializes a member store as fully empty connected to a room.
struct GNUNET_MESSENGER_Member * add_store_member(struct GNUNET_MESSENGER_MemberStore *store, const struct GNUNET_ShortHashCode *id)
Adds a member to a store under a specific id and returns it on success.
void clear_member_store(struct GNUNET_MESSENGER_MemberStore *store)
Clears a member store, wipes its content and deallocates its memory.
static int callback_scan_for_members(void *cls, const char *filename)
int(* GNUNET_MESSENGER_MemberIteratorCallback)(void *cls, const struct GNUNET_IDENTITY_PublicKey *public_key, struct GNUNET_MESSENGER_MemberSession *session)
const struct GNUNET_HashCode * get_room_key(const struct GNUNET_MESSENGER_SrvRoom *room)
Returns the shared secret you need to access a room.
GNUnet MESSENGER service.
struct GNUNET_MESSENGER_ContactStore * get_service_contact_store(struct GNUNET_MESSENGER_Service *service)
Returns the used contact store of a given service.
GNUnet MESSENGER service.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition: disk.c:404
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:496
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:814
int GNUNET_CONTAINER_multishortmap_iterate(struct GNUNET_CONTAINER_MultiShortmap *map, GNUNET_CONTAINER_ShortmapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
int GNUNET_CONTAINER_multishortmap_put(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
void * GNUNET_CONTAINER_multishortmap_get(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Given a key find a value in the map matching the key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_free(ptr)
Wrapper around free.
@ GNUNET_MESSENGER_KIND_INFO
The info kind.
@ GNUNET_MESSENGER_KIND_JOIN
The join kind.
#define DIR_SEPARATOR
Definition: platform.h:164
A 512-bit hashcode.
struct GNUNET_CONTAINER_MultiShortmap * members
struct GNUNET_MESSENGER_MemberStore * store
enum GNUNET_MESSENGER_MessageKind kind
The kind of the message.
struct GNUNET_ShortHashCode sender_id
The senders id inside of the room the message was sent in.
struct GNUNET_MESSENGER_MessageHeader header
Header.
struct GNUNET_MESSENGER_Service * service
A 256-bit hashcode.