aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/gnunet-service-messenger_service.c
diff options
context:
space:
mode:
authorTheJackiMonster <thejackimonster@gmail.com>2020-11-01 22:57:28 +0100
committerTheJackiMonster <thejackimonster@gmail.com>2021-03-06 01:30:37 +0100
commit2925310d67483aca6e055e1ce0593c6463cd6c72 (patch)
tree2cc8aacafc25563cdccde2eee9a90f9ca257d405 /src/messenger/gnunet-service-messenger_service.c
parent82b864a64679b0a735201724907cdf2b7e4e16c3 (diff)
downloadgnunet-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.c306
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
33static void 30static void
34callback_shutdown_service (void *cls) 31callback_shutdown_service (void *cls)
@@ -43,23 +40,11 @@ callback_shutdown_service (void *cls)
43 } 40 }
44} 41}
45 42
46static void
47callback_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
60struct GNUNET_MESSENGER_Service* 43struct GNUNET_MESSENGER_Service*
61create_service (const struct GNUNET_CONFIGURATION_Handle *config, struct GNUNET_SERVICE_Handle *service_handle) 44create_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
105static int 87 return service;
106iterate_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
113static int 90static 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
121static int
122iterate_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
129void 98void
130destroy_service (struct GNUNET_MESSENGER_Service *service) 99destroy_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
176struct GNUNET_MESSENGER_Ego* 137struct GNUNET_MESSENGER_EgoStore*
177lookup_service_ego (struct GNUNET_MESSENGER_Service *service, const char *identifier) 138get_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
187void 145struct GNUNET_MESSENGER_ContactStore*
188update_service_ego (struct GNUNET_MESSENGER_Service *service, const char *identifier, 146get_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
211struct GNUNET_MESSENGER_SrvHandle* 153struct GNUNET_MESSENGER_SrvHandle*
212add_service_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MQ_Handle *mq) 154add_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
224void 168void
225remove_service_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle) 169remove_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
234int 180int
235get_service_peer_identity (const struct GNUNET_MESSENGER_Service *service, struct GNUNET_PeerIdentity *peer) 181get_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
240struct GNUNET_MESSENGER_SrvContact* 185 return GNUNET_CRYPTO_get_peer_identity (service->config, peer);
241get_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
262void
263swap_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
279struct GNUNET_ShortHashCode*
280generate_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
296struct GNUNET_MESSENGER_SrvRoom* 188struct GNUNET_MESSENGER_SrvRoom*
297get_service_room (struct GNUNET_MESSENGER_Service *service, const struct GNUNET_HashCode *key) 189get_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
303open_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, 197open_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
322entry_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, 220entry_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
351close_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, 253close_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
396static void
397get_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
402void
403load_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
450void
451save_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
486void 292void
487handle_service_message (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room, 293handle_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}