diff options
author | TheJackiMonster <thejackimonster@gmail.com> | 2020-11-01 22:57:28 +0100 |
---|---|---|
committer | TheJackiMonster <thejackimonster@gmail.com> | 2021-03-06 01:30:37 +0100 |
commit | 2925310d67483aca6e055e1ce0593c6463cd6c72 (patch) | |
tree | 2cc8aacafc25563cdccde2eee9a90f9ca257d405 /src/messenger/gnunet-service-messenger_service.c | |
parent | 82b864a64679b0a735201724907cdf2b7e4e16c3 (diff) | |
download | gnunet-2925310d67483aca6e055e1ce0593c6463cd6c72.tar.gz gnunet-2925310d67483aca6e055e1ce0593c6463cd6c72.zip |
-added core functionality of the messenger service
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
formatting messenger code
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-completed core functionality of messenger service
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-code cleanup and reuse
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
+added structure to memberships of rooms
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-implemented member permission checks and deletion of messages
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-moved solving requests out of updating last messages (also forward before update)
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-reduced complexity of permisson check and changed load/save of rooms
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-added save/load for accessed keys and basement peers of a room
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-implemented save/load for members with their history and session
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-abstracted management of egos and contacts
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-fix warning
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-abstracted management of members
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-fixed and adjusted test case
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-separated handling of direct and anonymous contacts
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-messenger added member-sessions which fix multiple edge cases, also additional cleanup
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-updated docs and fixed memory leak
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-changed info messages and added protocol version exchange
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-adjusted client api to use contacts from sessions
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-added more logging and fixed wrong session usage
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-adjusted comm0 test case and removed adding members from checking messages
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-fixed test-case for peer exchange
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-getting multiple peers connected in test-case with cadet
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-fixed wrong assert and added tunnel version check
-simplified handling and forwarding
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-fixed merging last messages and cycling info messages
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-automated adding sessions and members
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-corrected use of identity keys and signatures
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-adding local joining on entering external room
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-fixed test-case comm0
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-added more test-cases with generic setup
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-fixed multiple simultaneous channels blocking each other
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-making test-cases more precise
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-added check of members in test-cases, reduced merge messages
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-unified delayed operations: requests, deletions and merges
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-finished handling of operations
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-fixed member session historystorage, added request permission check and padding for transmission
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-improved padding and removed automatic recursive requests
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-implemented filter for sending messages and added private messages to API level
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-wrong setups fixed with proper ego lookups
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-fixed problem with anonymous ego and changed to discrete-level padding
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-added links to replace deleted messages, added local deletion and fixed anonymous id changing
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-added session completion and removal through completion process
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
Diffstat (limited to 'src/messenger/gnunet-service-messenger_service.c')
-rw-r--r-- | src/messenger/gnunet-service-messenger_service.c | 306 |
1 files changed, 48 insertions, 258 deletions
diff --git a/src/messenger/gnunet-service-messenger_service.c b/src/messenger/gnunet-service-messenger_service.c index 963314fd8..8c63e9bf4 100644 --- a/src/messenger/gnunet-service-messenger_service.c +++ b/src/messenger/gnunet-service-messenger_service.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2020 GNUnet e.V. | 3 | Copyright (C) 2020--2021 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 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 | 6 | under the terms of the GNU Affero General Public License as published |
@@ -24,11 +24,8 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include "gnunet-service-messenger_service.h" | 26 | #include "gnunet-service-messenger_service.h" |
27 | |||
28 | #include "gnunet-service-messenger_message_kind.h" | 27 | #include "gnunet-service-messenger_message_kind.h" |
29 | |||
30 | #include "gnunet-service-messenger.h" | 28 | #include "gnunet-service-messenger.h" |
31 | #include "gnunet-service-messenger_util.h" | ||
32 | 29 | ||
33 | static void | 30 | static void |
34 | callback_shutdown_service (void *cls) | 31 | callback_shutdown_service (void *cls) |
@@ -43,23 +40,11 @@ callback_shutdown_service (void *cls) | |||
43 | } | 40 | } |
44 | } | 41 | } |
45 | 42 | ||
46 | static void | ||
47 | callback_update_ego (void *cls, | ||
48 | struct GNUNET_IDENTITY_Ego *ego, | ||
49 | void **ctx, | ||
50 | const char *identifier) | ||
51 | { | ||
52 | if ((!ego) || (!identifier)) | ||
53 | return; | ||
54 | |||
55 | struct GNUNET_MESSENGER_Service *service = cls; | ||
56 | |||
57 | update_service_ego(service, identifier, GNUNET_IDENTITY_ego_get_private_key(ego)); | ||
58 | } | ||
59 | |||
60 | struct GNUNET_MESSENGER_Service* | 43 | struct GNUNET_MESSENGER_Service* |
61 | create_service (const struct GNUNET_CONFIGURATION_Handle *config, struct GNUNET_SERVICE_Handle *service_handle) | 44 | create_service (const struct GNUNET_CONFIGURATION_Handle *config, struct GNUNET_SERVICE_Handle *service_handle) |
62 | { | 45 | { |
46 | GNUNET_assert((config) && (service_handle)); | ||
47 | |||
63 | struct GNUNET_MESSENGER_Service *service = GNUNET_new(struct GNUNET_MESSENGER_Service); | 48 | struct GNUNET_MESSENGER_Service *service = GNUNET_new(struct GNUNET_MESSENGER_Service); |
64 | 49 | ||
65 | service->config = config; | 50 | service->config = config; |
@@ -90,24 +75,16 @@ create_service (const struct GNUNET_CONFIGURATION_Handle *config, struct GNUNET_ | |||
90 | } | 75 | } |
91 | 76 | ||
92 | service->cadet = GNUNET_CADET_connect (service->config); | 77 | service->cadet = GNUNET_CADET_connect (service->config); |
93 | service->identity = GNUNET_IDENTITY_connect (service->config, &callback_update_ego, service); | ||
94 | 78 | ||
95 | service->egos = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); | 79 | init_ego_store(get_service_ego_store(service), service->config); |
96 | 80 | ||
97 | init_list_handles (&(service->handles)); | 81 | init_list_handles (&(service->handles)); |
98 | 82 | ||
99 | service->contacts = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); | ||
100 | service->rooms = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); | 83 | service->rooms = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); |
101 | 84 | ||
102 | return service; | 85 | init_contact_store(get_service_contact_store(service)); |
103 | } | ||
104 | 86 | ||
105 | static int | 87 | return service; |
106 | iterate_destroy_egos (void *cls, const struct GNUNET_HashCode *key, void *value) | ||
107 | { | ||
108 | struct GNUNET_MESSENGER_Ego *ego = value; | ||
109 | GNUNET_free(ego); | ||
110 | return GNUNET_YES; | ||
111 | } | 88 | } |
112 | 89 | ||
113 | static int | 90 | static int |
@@ -118,17 +95,11 @@ iterate_destroy_rooms (void *cls, const struct GNUNET_HashCode *key, void *value | |||
118 | return GNUNET_YES; | 95 | return GNUNET_YES; |
119 | } | 96 | } |
120 | 97 | ||
121 | static int | ||
122 | iterate_destroy_contacts (void *cls, const struct GNUNET_HashCode *key, void *value) | ||
123 | { | ||
124 | struct GNUNET_MESSENGER_SrvContact *contact = value; | ||
125 | destroy_contact (contact); | ||
126 | return GNUNET_YES; | ||
127 | } | ||
128 | |||
129 | void | 98 | void |
130 | destroy_service (struct GNUNET_MESSENGER_Service *service) | 99 | destroy_service (struct GNUNET_MESSENGER_Service *service) |
131 | { | 100 | { |
101 | GNUNET_assert(service); | ||
102 | |||
132 | if (service->shutdown) | 103 | if (service->shutdown) |
133 | { | 104 | { |
134 | GNUNET_SCHEDULER_cancel (service->shutdown); | 105 | GNUNET_SCHEDULER_cancel (service->shutdown); |
@@ -136,16 +107,13 @@ destroy_service (struct GNUNET_MESSENGER_Service *service) | |||
136 | service->shutdown = NULL; | 107 | service->shutdown = NULL; |
137 | } | 108 | } |
138 | 109 | ||
139 | GNUNET_CONTAINER_multihashmap_iterate (service->egos, iterate_destroy_egos, NULL); | 110 | clear_ego_store(get_service_ego_store(service)); |
140 | |||
141 | clear_list_handles (&(service->handles)); | 111 | clear_list_handles (&(service->handles)); |
142 | 112 | ||
143 | GNUNET_CONTAINER_multihashmap_iterate (service->rooms, iterate_destroy_rooms, NULL); | 113 | GNUNET_CONTAINER_multihashmap_iterate (service->rooms, iterate_destroy_rooms, NULL); |
144 | GNUNET_CONTAINER_multihashmap_iterate (service->contacts, iterate_destroy_contacts, NULL); | ||
145 | |||
146 | GNUNET_CONTAINER_multihashmap_destroy (service->egos); | ||
147 | GNUNET_CONTAINER_multihashmap_destroy (service->rooms); | 114 | GNUNET_CONTAINER_multihashmap_destroy (service->rooms); |
148 | GNUNET_CONTAINER_multihashmap_destroy (service->contacts); | 115 | |
116 | clear_contact_store(get_service_contact_store(service)); | ||
149 | 117 | ||
150 | if (service->cadet) | 118 | if (service->cadet) |
151 | { | 119 | { |
@@ -154,13 +122,6 @@ destroy_service (struct GNUNET_MESSENGER_Service *service) | |||
154 | service->cadet = NULL; | 122 | service->cadet = NULL; |
155 | } | 123 | } |
156 | 124 | ||
157 | if (service->identity) | ||
158 | { | ||
159 | GNUNET_IDENTITY_disconnect (service->identity); | ||
160 | |||
161 | service->identity = NULL; | ||
162 | } | ||
163 | |||
164 | if (service->dir) | 125 | if (service->dir) |
165 | { | 126 | { |
166 | GNUNET_free(service->dir); | 127 | GNUNET_free(service->dir); |
@@ -173,44 +134,27 @@ destroy_service (struct GNUNET_MESSENGER_Service *service) | |||
173 | GNUNET_free(service); | 134 | GNUNET_free(service); |
174 | } | 135 | } |
175 | 136 | ||
176 | struct GNUNET_MESSENGER_Ego* | 137 | struct GNUNET_MESSENGER_EgoStore* |
177 | lookup_service_ego (struct GNUNET_MESSENGER_Service *service, const char *identifier) | 138 | get_service_ego_store (struct GNUNET_MESSENGER_Service *service) |
178 | { | 139 | { |
179 | GNUNET_assert(identifier); | 140 | GNUNET_assert(service); |
180 | 141 | ||
181 | struct GNUNET_HashCode hash; | 142 | return &(service->ego_store); |
182 | |||
183 | GNUNET_CRYPTO_hash(identifier, strlen(identifier), &hash); | ||
184 | return GNUNET_CONTAINER_multihashmap_get(service->egos, &hash); | ||
185 | } | 143 | } |
186 | 144 | ||
187 | void | 145 | struct GNUNET_MESSENGER_ContactStore* |
188 | update_service_ego (struct GNUNET_MESSENGER_Service *service, const char *identifier, | 146 | get_service_contact_store (struct GNUNET_MESSENGER_Service *service) |
189 | const struct GNUNET_IDENTITY_PrivateKey* key) | ||
190 | { | 147 | { |
191 | GNUNET_assert((identifier) && (key)); | 148 | GNUNET_assert(service); |
192 | |||
193 | struct GNUNET_HashCode hash; | ||
194 | |||
195 | GNUNET_CRYPTO_hash(identifier, strlen(identifier), &hash); | ||
196 | 149 | ||
197 | struct GNUNET_MESSENGER_Ego* ego = GNUNET_CONTAINER_multihashmap_get(service->egos, &hash); | 150 | return &(service->contact_store); |
198 | |||
199 | if (!ego) | ||
200 | { | ||
201 | ego = GNUNET_new(struct GNUNET_MESSENGER_Ego); | ||
202 | GNUNET_CONTAINER_multihashmap_put(service->egos, &hash, ego, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
203 | } | ||
204 | |||
205 | GNUNET_memcpy(&(ego->priv), key, sizeof(*key)); | ||
206 | |||
207 | if (GNUNET_OK != GNUNET_IDENTITY_key_get_public(key, &(ego->pub))) | ||
208 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Updating invalid ego key failed!\n"); | ||
209 | } | 151 | } |
210 | 152 | ||
211 | struct GNUNET_MESSENGER_SrvHandle* | 153 | struct GNUNET_MESSENGER_SrvHandle* |
212 | add_service_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MQ_Handle *mq) | 154 | add_service_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MQ_Handle *mq) |
213 | { | 155 | { |
156 | GNUNET_assert((service) && (mq)); | ||
157 | |||
214 | struct GNUNET_MESSENGER_SrvHandle *handle = create_handle (service, mq); | 158 | struct GNUNET_MESSENGER_SrvHandle *handle = create_handle (service, mq); |
215 | 159 | ||
216 | if (handle) | 160 | if (handle) |
@@ -224,6 +168,8 @@ add_service_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MQ_H | |||
224 | void | 168 | void |
225 | remove_service_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle) | 169 | remove_service_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle) |
226 | { | 170 | { |
171 | GNUNET_assert((service) && (handle)); | ||
172 | |||
227 | if (!handle) | 173 | if (!handle) |
228 | return; | 174 | return; |
229 | 175 | ||
@@ -234,68 +180,16 @@ remove_service_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_M | |||
234 | int | 180 | int |
235 | get_service_peer_identity (const struct GNUNET_MESSENGER_Service *service, struct GNUNET_PeerIdentity *peer) | 181 | get_service_peer_identity (const struct GNUNET_MESSENGER_Service *service, struct GNUNET_PeerIdentity *peer) |
236 | { | 182 | { |
237 | return GNUNET_CRYPTO_get_peer_identity (service->config, peer); | 183 | GNUNET_assert((service) && (peer)); |
238 | } | ||
239 | 184 | ||
240 | struct GNUNET_MESSENGER_SrvContact* | 185 | return GNUNET_CRYPTO_get_peer_identity (service->config, peer); |
241 | get_service_contact_by_pubkey (struct GNUNET_MESSENGER_Service *service, const struct GNUNET_IDENTITY_PublicKey *pubkey) | ||
242 | { | ||
243 | struct GNUNET_HashCode hash; | ||
244 | |||
245 | GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash); | ||
246 | |||
247 | struct GNUNET_MESSENGER_SrvContact *contact = GNUNET_CONTAINER_multihashmap_get (service->contacts, &hash); | ||
248 | |||
249 | if (contact) | ||
250 | return contact; | ||
251 | |||
252 | contact = create_contact (pubkey); | ||
253 | |||
254 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (service->contacts, &hash, contact, | ||
255 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
256 | return contact; | ||
257 | |||
258 | destroy_contact (contact); | ||
259 | return NULL; | ||
260 | } | ||
261 | |||
262 | void | ||
263 | swap_service_contact_by_pubkey (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvContact *contact, | ||
264 | const struct GNUNET_IDENTITY_PublicKey *pubkey) | ||
265 | { | ||
266 | const struct GNUNET_HashCode *hash = get_contact_id_from_key (contact); | ||
267 | |||
268 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (service->contacts, hash, contact)) | ||
269 | { | ||
270 | GNUNET_memcpy(&(contact->public_key), pubkey, sizeof(*pubkey)); | ||
271 | |||
272 | hash = get_contact_id_from_key (contact); | ||
273 | |||
274 | GNUNET_CONTAINER_multihashmap_put (service->contacts, hash, contact, | ||
275 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
276 | } | ||
277 | } | ||
278 | |||
279 | struct GNUNET_ShortHashCode* | ||
280 | generate_service_new_member_id (struct GNUNET_MESSENGER_Service *service, const struct GNUNET_HashCode *key) | ||
281 | { | ||
282 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (service, key); | ||
283 | |||
284 | if (room) | ||
285 | { | ||
286 | return generate_room_member_id (room); | ||
287 | } | ||
288 | else | ||
289 | { | ||
290 | struct GNUNET_ShortHashCode *random_id = GNUNET_new(struct GNUNET_ShortHashCode); | ||
291 | generate_free_member_id (random_id, NULL); | ||
292 | return random_id; | ||
293 | } | ||
294 | } | 186 | } |
295 | 187 | ||
296 | struct GNUNET_MESSENGER_SrvRoom* | 188 | struct GNUNET_MESSENGER_SrvRoom* |
297 | get_service_room (struct GNUNET_MESSENGER_Service *service, const struct GNUNET_HashCode *key) | 189 | get_service_room (const struct GNUNET_MESSENGER_Service *service, const struct GNUNET_HashCode *key) |
298 | { | 190 | { |
191 | GNUNET_assert((service) && (key)); | ||
192 | |||
299 | return GNUNET_CONTAINER_multihashmap_get (service->rooms, key); | 193 | return GNUNET_CONTAINER_multihashmap_get (service->rooms, key); |
300 | } | 194 | } |
301 | 195 | ||
@@ -303,6 +197,8 @@ int | |||
303 | open_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, | 197 | open_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, |
304 | const struct GNUNET_HashCode *key) | 198 | const struct GNUNET_HashCode *key) |
305 | { | 199 | { |
200 | GNUNET_assert((service) && (handle) && (key)); | ||
201 | |||
306 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (service, key); | 202 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (service, key); |
307 | 203 | ||
308 | if (room) | 204 | if (room) |
@@ -310,8 +206,10 @@ open_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSE | |||
310 | 206 | ||
311 | room = create_room (handle, key); | 207 | room = create_room (handle, key); |
312 | 208 | ||
313 | if ((GNUNET_YES == open_room (room, handle)) && (GNUNET_OK | 209 | if ((GNUNET_YES == open_room (room, handle)) && |
314 | == GNUNET_CONTAINER_multihashmap_put (service->rooms, key, room, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) | 210 | (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (service->rooms, |
211 | key, room, | ||
212 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) | ||
315 | return GNUNET_YES; | 213 | return GNUNET_YES; |
316 | 214 | ||
317 | destroy_room (room); | 215 | destroy_room (room); |
@@ -322,11 +220,13 @@ int | |||
322 | entry_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, | 220 | entry_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, |
323 | const struct GNUNET_PeerIdentity *door, const struct GNUNET_HashCode *key) | 221 | const struct GNUNET_PeerIdentity *door, const struct GNUNET_HashCode *key) |
324 | { | 222 | { |
223 | GNUNET_assert((service) && (handle) && (door) && (key)); | ||
224 | |||
325 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (service, key); | 225 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (service, key); |
326 | 226 | ||
327 | if (room) | 227 | if (room) |
328 | { | 228 | { |
329 | if (GNUNET_YES == entry_room_at (room, handle, door)) | 229 | if (GNUNET_YES == enter_room_at (room, handle, door)) |
330 | return GNUNET_YES; | 230 | return GNUNET_YES; |
331 | else | 231 | else |
332 | return GNUNET_NO; | 232 | return GNUNET_NO; |
@@ -334,8 +234,10 @@ entry_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESS | |||
334 | 234 | ||
335 | room = create_room (handle, key); | 235 | room = create_room (handle, key); |
336 | 236 | ||
337 | if ((GNUNET_YES == entry_room_at (room, handle, door)) && (GNUNET_OK | 237 | if ((GNUNET_YES == enter_room_at (room, handle, door)) && |
338 | == GNUNET_CONTAINER_multihashmap_put (service->rooms, key, room, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) | 238 | (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (service->rooms, |
239 | key, room, | ||
240 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) | ||
339 | { | 241 | { |
340 | return GNUNET_YES; | 242 | return GNUNET_YES; |
341 | } | 243 | } |
@@ -351,20 +253,14 @@ int | |||
351 | close_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, | 253 | close_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, |
352 | const struct GNUNET_HashCode *key) | 254 | const struct GNUNET_HashCode *key) |
353 | { | 255 | { |
256 | GNUNET_assert((service) && (handle) && (key)); | ||
257 | |||
354 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (service, key); | 258 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (service, key); |
355 | 259 | ||
356 | if (!room) | 260 | if (!room) |
357 | return GNUNET_NO; | 261 | return GNUNET_NO; |
358 | 262 | ||
359 | struct GNUNET_MESSENGER_Message *message = create_message_leave (); | 263 | send_room_message (room, handle, create_message_leave ()); |
360 | |||
361 | if (message) | ||
362 | { | ||
363 | struct GNUNET_HashCode hash; | ||
364 | |||
365 | send_room_message (room, handle, message, &hash); | ||
366 | destroy_message (message); | ||
367 | } | ||
368 | 264 | ||
369 | const struct GNUNET_ShortHashCode *id = get_handle_member_id (handle, key); | 265 | const struct GNUNET_ShortHashCode *id = get_handle_member_id (handle, key); |
370 | 266 | ||
@@ -393,124 +289,18 @@ close_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESS | |||
393 | return GNUNET_YES; | 289 | return GNUNET_YES; |
394 | } | 290 | } |
395 | 291 | ||
396 | static void | ||
397 | get_room_data_subdir (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room, char **dir) | ||
398 | { | ||
399 | GNUNET_asprintf (dir, "%s%s%c%s%c", service->dir, "rooms", DIR_SEPARATOR, GNUNET_h2s (&(room->key)), DIR_SEPARATOR); | ||
400 | } | ||
401 | |||
402 | void | ||
403 | load_service_room_and_messages (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room) | ||
404 | { | ||
405 | char *room_dir; | ||
406 | get_room_data_subdir (service, room, &room_dir); | ||
407 | |||
408 | if (GNUNET_YES == GNUNET_DISK_directory_test (room_dir, GNUNET_YES)) | ||
409 | { | ||
410 | load_message_store (&room->store, room_dir); | ||
411 | |||
412 | char *config_file; | ||
413 | GNUNET_asprintf (&config_file, "%s%s", room_dir, "room.cfg"); | ||
414 | |||
415 | struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); | ||
416 | |||
417 | if ((GNUNET_YES == GNUNET_DISK_file_test (config_file)) && (GNUNET_OK | ||
418 | == GNUNET_CONFIGURATION_parse (cfg, config_file))) | ||
419 | { | ||
420 | unsigned long long access; | ||
421 | |||
422 | if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "room", "access-rule", &access)) | ||
423 | room->strict_access = (int) (access); | ||
424 | |||
425 | char *message_string; | ||
426 | |||
427 | if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, "room", "last-message", &message_string)) && (message_string)) | ||
428 | { | ||
429 | struct GNUNET_HashCode hash; | ||
430 | |||
431 | GNUNET_CRYPTO_hash_from_string(message_string, &hash); | ||
432 | |||
433 | const struct GNUNET_MESSENGER_Message *message = get_room_message (room, room->host, &hash, GNUNET_NO); | ||
434 | |||
435 | if (message) | ||
436 | update_room_last_messages (room, message, &hash); | ||
437 | |||
438 | GNUNET_free(message_string); | ||
439 | } | ||
440 | } | ||
441 | |||
442 | GNUNET_CONFIGURATION_destroy (cfg); | ||
443 | |||
444 | GNUNET_free(config_file); | ||
445 | } | ||
446 | |||
447 | GNUNET_free(room_dir); | ||
448 | } | ||
449 | |||
450 | void | ||
451 | save_service_room_and_messages (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room) | ||
452 | { | ||
453 | if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (service->rooms, &(room->key))) | ||
454 | { | ||
455 | return; | ||
456 | } | ||
457 | |||
458 | char *room_dir; | ||
459 | get_room_data_subdir (service, room, &room_dir); | ||
460 | |||
461 | if ((GNUNET_YES == GNUNET_DISK_directory_test (room_dir, GNUNET_NO)) || (GNUNET_OK | ||
462 | == GNUNET_DISK_directory_create (room_dir))) | ||
463 | { | ||
464 | save_message_store (&room->store, room_dir); | ||
465 | |||
466 | char *config_file; | ||
467 | GNUNET_asprintf (&config_file, "%s%s", room_dir, "room.cfg"); | ||
468 | |||
469 | struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); | ||
470 | |||
471 | GNUNET_CONFIGURATION_set_value_number (cfg, "room", "access-rule", room->strict_access); | ||
472 | |||
473 | if (room->last_messages.head) | ||
474 | GNUNET_CONFIGURATION_set_value_string (cfg, "room", "last-message", | ||
475 | GNUNET_h2s_full (&(room->last_messages.head->hash))); | ||
476 | |||
477 | GNUNET_CONFIGURATION_write (cfg, config_file); | ||
478 | GNUNET_CONFIGURATION_destroy (cfg); | ||
479 | |||
480 | GNUNET_free(config_file); | ||
481 | } | ||
482 | |||
483 | GNUNET_free(room_dir); | ||
484 | } | ||
485 | |||
486 | void | 292 | void |
487 | handle_service_message (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room, | 293 | handle_service_message (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room, |
294 | const struct GNUNET_MESSENGER_MemberSession *session, | ||
488 | const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) | 295 | const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) |
489 | { | 296 | { |
490 | struct GNUNET_MESSENGER_ListHandle *element = service->handles.head; | 297 | GNUNET_assert((service) && (room) && (session) && (message) && (hash)); |
491 | 298 | ||
492 | const uint16_t length = get_message_size (message); | 299 | struct GNUNET_MESSENGER_ListHandle *element = service->handles.head; |
493 | 300 | ||
494 | while (element) | 301 | while (element) |
495 | { | 302 | { |
496 | struct GNUNET_MESSENGER_SrvHandle *handle = (struct GNUNET_MESSENGER_SrvHandle*) element->handle; | 303 | notify_handle_message (element->handle, get_room_key(room), session, message, hash); |
497 | |||
498 | if ((handle->mq) && (get_handle_member_id (handle, &(room->key)))) | ||
499 | { | ||
500 | struct GNUNET_MESSENGER_RecvMessage *msg; | ||
501 | struct GNUNET_MQ_Envelope *env; | ||
502 | |||
503 | env = GNUNET_MQ_msg_extra(msg, length, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE); | ||
504 | |||
505 | GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key)); | ||
506 | GNUNET_memcpy(&(msg->hash), hash, sizeof(*hash)); | ||
507 | |||
508 | char *buffer = ((char*) msg) + sizeof(*msg); | ||
509 | encode_message (message, length, buffer); | ||
510 | |||
511 | GNUNET_MQ_send (handle->mq, env); | ||
512 | } | ||
513 | |||
514 | element = element->next; | 304 | element = element->next; |
515 | } | 305 | } |
516 | } | 306 | } |