aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/gnunet-service-messenger_handle.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/messenger/gnunet-service-messenger_handle.c')
-rw-r--r--src/messenger/gnunet-service-messenger_handle.c541
1 files changed, 170 insertions, 371 deletions
diff --git a/src/messenger/gnunet-service-messenger_handle.c b/src/messenger/gnunet-service-messenger_handle.c
index 17692761d..ddb437b7e 100644
--- a/src/messenger/gnunet-service-messenger_handle.c
+++ b/src/messenger/gnunet-service-messenger_handle.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--2022 GNUnet e.V. 3 Copyright (C) 2020--2023 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
@@ -27,10 +27,15 @@
27#include "gnunet-service-messenger_handle.h" 27#include "gnunet-service-messenger_handle.h"
28 28
29#include "gnunet-service-messenger.h" 29#include "gnunet-service-messenger.h"
30#include "gnunet-service-messenger_message_kind.h" 30#include "messenger_api_message_kind.h"
31
32#include "messenger_api_util.h" 31#include "messenger_api_util.h"
33 32
33struct GNUNET_MESSENGER_NextMemberId
34{
35 struct GNUNET_ShortHashCode id;
36 enum GNUNET_GenericReturnValue reset;
37};
38
34struct GNUNET_MESSENGER_SrvHandle* 39struct GNUNET_MESSENGER_SrvHandle*
35create_srv_handle (struct GNUNET_MESSENGER_Service *service, 40create_srv_handle (struct GNUNET_MESSENGER_Service *service,
36 struct GNUNET_MQ_Handle *mq) 41 struct GNUNET_MQ_Handle *mq)
@@ -42,10 +47,10 @@ create_srv_handle (struct GNUNET_MESSENGER_Service *service,
42 handle->service = service; 47 handle->service = service;
43 handle->mq = mq; 48 handle->mq = mq;
44 49
45 handle->name = NULL;
46 handle->ego = NULL;
47
48 handle->member_ids = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); 50 handle->member_ids = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
51 handle->next_ids = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
52
53 handle->notify = NULL;
49 54
50 return handle; 55 return handle;
51} 56}
@@ -65,22 +70,42 @@ destroy_srv_handle (struct GNUNET_MESSENGER_SrvHandle *handle)
65{ 70{
66 GNUNET_assert(handle); 71 GNUNET_assert(handle);
67 72
68 if (handle->service->dir) 73 if (handle->notify)
69 save_srv_handle_configuration (handle); 74 GNUNET_SCHEDULER_cancel(handle->notify);
70 75
71 if (handle->name) 76 GNUNET_CONTAINER_multihashmap_iterate (handle->next_ids, iterate_free_member_ids, NULL);
72 { 77 GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_free_member_ids, NULL);
73 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service); 78
79 GNUNET_CONTAINER_multihashmap_destroy (handle->next_ids);
80 GNUNET_CONTAINER_multihashmap_destroy (handle->member_ids);
74 81
75 unbind_store_ego(store, handle->name, handle); 82 GNUNET_free(handle);
83}
84
85void
86set_srv_handle_key (struct GNUNET_MESSENGER_SrvHandle *handle,
87 const struct GNUNET_IDENTITY_PublicKey *key)
88{
89 GNUNET_assert(handle);
76 90
77 GNUNET_free(handle->name); 91 if ((handle->key) && (!key))
92 {
93 GNUNET_free(handle->key);
94 handle->key = NULL;
78 } 95 }
96 else if (!handle->key)
97 handle->key = GNUNET_new(struct GNUNET_IDENTITY_PublicKey);
79 98
80 GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_free_member_ids, NULL); 99 if (key)
81 GNUNET_CONTAINER_multihashmap_destroy (handle->member_ids); 100 memcpy(handle->key, key, sizeof(struct GNUNET_IDENTITY_PublicKey));
101}
82 102
83 GNUNET_free(handle); 103const struct GNUNET_IDENTITY_PublicKey*
104get_srv_handle_key (const struct GNUNET_MESSENGER_SrvHandle *handle)
105{
106 GNUNET_assert(handle);
107
108 return handle->key;
84} 109}
85 110
86void 111void
@@ -156,7 +181,7 @@ change_srv_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle,
156 } 181 }
157 182
158 if (0 == GNUNET_memcmp(unique_id, member_id)) 183 if (0 == GNUNET_memcmp(unique_id, member_id))
159 goto send_message_to_client; 184 return GNUNET_OK;
160 185
161 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Change a member id (%s) for room (%s).\n", GNUNET_sh2s (member_id), 186 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Change a member id (%s) for room (%s).\n", GNUNET_sh2s (member_id),
162 GNUNET_h2s (key)); 187 GNUNET_h2s (key));
@@ -164,264 +189,70 @@ change_srv_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle,
164 GNUNET_memcpy(member_id, unique_id, sizeof(*unique_id)); 189 GNUNET_memcpy(member_id, unique_id, sizeof(*unique_id));
165 190
166 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Member id changed to (%s).\n", GNUNET_sh2s (unique_id)); 191 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Member id changed to (%s).\n", GNUNET_sh2s (unique_id));
167
168 struct GNUNET_MESSENGER_MemberMessage *msg;
169 struct GNUNET_MQ_Envelope *env;
170
171send_message_to_client:
172
173 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID);
174
175 GNUNET_memcpy(&(msg->key), key, sizeof(*key));
176 GNUNET_memcpy(&(msg->id), member_id, sizeof(*member_id));
177
178 GNUNET_MQ_send (handle->mq, env);
179 return GNUNET_OK; 192 return GNUNET_OK;
180} 193}
181 194
182static void 195struct RoomInitializationClosure
183change_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle,
184 const char *name)
185{
186 GNUNET_assert(handle);
187
188 if (handle->name)
189 GNUNET_free(handle->name);
190
191 handle->name = name ? GNUNET_strdup(name) : NULL;
192
193 const uint16_t name_len = handle->name ? strlen (handle->name) : 0;
194
195 struct GNUNET_MESSENGER_NameMessage *msg;
196 struct GNUNET_MQ_Envelope *env;
197
198 env = GNUNET_MQ_msg_extra(msg, name_len + 1, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_NAME);
199
200 char *extra = ((char*) msg) + sizeof(*msg);
201
202 if (name_len)
203 GNUNET_memcpy(extra, handle->name, name_len);
204
205 extra[name_len] = '\0';
206
207 GNUNET_MQ_send (handle->mq, env);
208}
209
210static void
211change_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle,
212 const struct GNUNET_MESSENGER_Ego *ego)
213{
214 GNUNET_assert(handle);
215
216 handle->ego = ego;
217
218 ego = get_srv_handle_ego (handle);
219
220 const uint16_t length = GNUNET_IDENTITY_public_key_get_length(&(ego->pub));
221
222 struct GNUNET_MESSENGER_KeyMessage *msg;
223 struct GNUNET_MQ_Envelope *env;
224
225 env = GNUNET_MQ_msg_extra(msg, length, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY);
226
227 char *extra = ((char*) msg) + sizeof(*msg);
228
229 if (GNUNET_IDENTITY_write_public_key_to_buffer(&(ego->pub), extra, length) < 0)
230 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Could not write key to buffer.\n");
231
232 GNUNET_MQ_send (handle->mq, env);
233}
234
235struct GNUNET_MESSENGER_MessageHandle
236{ 196{
237 struct GNUNET_MESSENGER_SrvHandle *handle; 197 struct GNUNET_MESSENGER_SrvHandle *handle;
238 struct GNUNET_MESSENGER_Message *message; 198 const struct GNUNET_HashCode *key;
199 const struct GNUNET_IDENTITY_PublicKey *pubkey;
239}; 200};
240 201
241static int 202static int
242iterate_send_message (void *cls, 203find_member_session_in_room (void *cls,
243 const struct GNUNET_HashCode *key, 204 const struct GNUNET_IDENTITY_PublicKey *public_key,
244 void *value) 205 struct GNUNET_MESSENGER_MemberSession *session)
245{
246 struct GNUNET_MESSENGER_MessageHandle *msg_handle = cls;
247
248 send_srv_handle_message (msg_handle->handle, key, msg_handle->message);
249
250 return GNUNET_YES;
251}
252
253void
254set_srv_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle,
255 const struct GNUNET_MESSENGER_Ego *ego)
256{ 206{
257 GNUNET_assert((handle) && (ego)); 207 struct RoomInitializationClosure *init = cls;
258
259 struct GNUNET_MESSENGER_MessageHandle msg_handle;
260
261 msg_handle.handle = handle;
262 msg_handle.message = create_message_key (&(ego->priv));
263
264 GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_send_message, &msg_handle);
265
266 destroy_message (msg_handle.message);
267 208
268 change_handle_ego (handle, ego); 209 if (!public_key)
269} 210 return GNUNET_YES;
270 211
271const struct GNUNET_MESSENGER_Ego* 212 const struct GNUNET_IDENTITY_PublicKey *pubkey = get_srv_handle_key(init->handle);
272get_srv_handle_ego (const struct GNUNET_MESSENGER_SrvHandle *handle)
273{
274 GNUNET_assert(handle);
275 213
276 static struct GNUNET_MESSENGER_Ego anonymous; 214 if (0 != GNUNET_memcmp(pubkey, public_key))
277 static int read_keys = 0; 215 return GNUNET_YES;
278 216
279 if (handle->ego) 217 const struct GNUNET_ShortHashCode *id = get_member_session_id(session);
280 return handle->ego;
281 218
282 if (!read_keys) 219 if (!id)
283 { 220 {
284 struct GNUNET_IDENTITY_Ego *ego = GNUNET_IDENTITY_ego_get_anonymous (); 221 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initialitation: Missing member id!");
285 GNUNET_memcpy(&(anonymous.priv), GNUNET_IDENTITY_ego_get_private_key (ego), sizeof(anonymous.priv)); 222 return GNUNET_NO;
286 GNUNET_IDENTITY_ego_get_public_key (ego, &(anonymous.pub));
287 read_keys = 1;
288 } 223 }
289 224
290 return &anonymous; 225 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Initialitation: Matching member found (%s)!\n",
291} 226 GNUNET_sh2s(id));
292 227
293static void 228 change_srv_handle_member_id(init->handle, init->key, id);
294callback_setup_handle_name (void *cls, 229 return GNUNET_NO;
295 const char *name,
296 const struct GNUNET_MESSENGER_Ego *ego)
297{
298 struct GNUNET_MESSENGER_SrvHandle *handle = cls;
299
300 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Setting up handle...\n");
301
302 change_handle_name (handle, name);
303 change_handle_ego (handle, ego);
304
305 if (handle->service->dir)
306 load_srv_handle_configuration (handle);
307}
308
309void
310setup_srv_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle,
311 const char *name)
312{
313 GNUNET_assert(handle);
314
315 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service);
316
317 lookup_store_ego (store, name, callback_setup_handle_name, handle);
318} 230}
319 231
320static void 232static void
321callback_update_handle (void *cls, 233initialize_srv_handle_via_matching_member (struct GNUNET_MESSENGER_SrvHandle *handle,
322 const char *name, 234 const struct GNUNET_HashCode *key)
323 const struct GNUNET_MESSENGER_Ego *ego)
324{ 235{
325 struct GNUNET_MESSENGER_SrvHandle *handle = cls; 236 struct GNUNET_MESSENGER_SrvRoom *room = get_service_room(handle->service, key);
326 237 if (!room)
327 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating handle...\n");
328
329 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service);
330
331 bind_store_ego(store, handle->name, handle);
332
333 if (!ego)
334 create_store_ego (store, handle->name);
335 else
336 renew_store_ego (store, handle->name);
337}
338
339void
340update_srv_handle (struct GNUNET_MESSENGER_SrvHandle *handle)
341{
342 GNUNET_assert (handle);
343
344 if (!handle->name)
345 {
346 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Updating handle failed: Name is required!\n");
347 return; 238 return;
348 }
349 239
350 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service); 240 struct GNUNET_MESSENGER_MemberStore *store = get_srv_room_member_store(room);
351 241 if (!store)
352 lookup_store_ego (store, handle->name, callback_update_handle, handle);
353}
354
355static void
356callback_set_handle_name (void *cls,
357 const char *name,
358 const struct GNUNET_MESSENGER_Ego *ego)
359{
360 struct GNUNET_MESSENGER_SrvHandle *handle = cls;
361
362 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Renaming handle...\n");
363
364 if (ego)
365 {
366 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Renaming handle failed: Name is occupied! (%s)\n", name);
367 return; 242 return;
368 }
369
370 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service);
371
372 char *old_dir;
373 get_srv_handle_data_subdir (handle, handle->name, &old_dir);
374
375 char *new_dir;
376 get_srv_handle_data_subdir (handle, name, &new_dir);
377
378 if ((GNUNET_YES == GNUNET_DISK_directory_test (new_dir, GNUNET_NO)) &&
379 (GNUNET_OK != GNUNET_DISK_directory_remove(new_dir)))
380 goto free_dirs;
381
382 if (GNUNET_YES == GNUNET_DISK_directory_test (old_dir, GNUNET_YES))
383 {
384 GNUNET_DISK_directory_create_for_file (new_dir);
385
386 if (0 != rename (old_dir, new_dir))
387 goto free_dirs;
388 }
389
390 if (handle->ego)
391 rename_store_ego(store, handle->name, name);
392
393 struct GNUNET_MESSENGER_MessageHandle msg_handle;
394 msg_handle.handle = handle;
395 msg_handle.message = create_message_name (name);
396
397 GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_send_message, &msg_handle);
398 destroy_message (msg_handle.message);
399 change_handle_name (handle, name);
400
401free_dirs:
402 GNUNET_free(old_dir);
403 GNUNET_free(new_dir);
404}
405
406void
407set_srv_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle,
408 const char *name)
409{
410 GNUNET_assert(handle);
411
412 if (!name)
413 {
414 if (handle->ego)
415 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Renaming handle failed: Name is required!\n");
416 else
417 change_handle_name (handle, name);
418 243
244 const struct GNUNET_IDENTITY_PublicKey *pubkey = get_srv_handle_key(handle);
245 if ((!pubkey) || (0 == GNUNET_memcmp (pubkey, get_anonymous_public_key())))
419 return; 246 return;
420 }
421 247
422 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service); 248 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initialize member id of handle via matching member in room!\n");
249
250 struct RoomInitializationClosure init;
251 init.handle = handle;
252 init.key = key;
253 init.pubkey = pubkey;
423 254
424 lookup_store_ego (store, name, callback_set_handle_name, handle); 255 iterate_store_members(store, find_member_session_in_room, &init);
425} 256}
426 257
427int 258int
@@ -430,6 +261,8 @@ open_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle,
430{ 261{
431 GNUNET_assert((handle) && (key)); 262 GNUNET_assert((handle) && (key));
432 263
264 initialize_srv_handle_via_matching_member (handle, key);
265
433 if ((!get_srv_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key))) 266 if ((!get_srv_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key)))
434 return GNUNET_NO; 267 return GNUNET_NO;
435 268
@@ -443,6 +276,8 @@ entry_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle,
443{ 276{
444 GNUNET_assert((handle) && (door) && (key)); 277 GNUNET_assert((handle) && (door) && (key));
445 278
279 initialize_srv_handle_via_matching_member (handle, key);
280
446 if ((!get_srv_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key))) 281 if ((!get_srv_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key)))
447 return GNUNET_NO; 282 return GNUNET_NO;
448 283
@@ -455,6 +290,15 @@ close_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle,
455{ 290{
456 GNUNET_assert((handle) && (key)); 291 GNUNET_assert((handle) && (key));
457 292
293 GNUNET_CONTAINER_multihashmap_get_multiple (handle->next_ids, key, iterate_free_member_ids, NULL);
294 GNUNET_CONTAINER_multihashmap_remove_all (handle->next_ids, key);
295
296 if ((handle->notify) && (0 == GNUNET_CONTAINER_multihashmap_size (handle->next_ids)))
297 {
298 GNUNET_SCHEDULER_cancel(handle->notify);
299 handle->notify = NULL;
300 }
301
458 if (!get_srv_handle_member_id (handle, key)) 302 if (!get_srv_handle_member_id (handle, key))
459 return GNUNET_NO; 303 return GNUNET_NO;
460 304
@@ -476,6 +320,15 @@ send_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle,
476 return GNUNET_NO; 320 return GNUNET_NO;
477 } 321 }
478 322
323 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending message with member id: %s\n",
324 GNUNET_sh2s (id));
325
326 if (0 != GNUNET_memcmp(id, &(message->header.sender_id)))
327 {
328 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Member id does not match with handle!\n");
329 return GNUNET_NO;
330 }
331
479 struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (handle->service, key); 332 struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (handle->service, key);
480 333
481 if (!room) 334 if (!room)
@@ -485,17 +338,14 @@ send_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle,
485 } 338 }
486 339
487 struct GNUNET_MESSENGER_Message *msg = copy_message(message); 340 struct GNUNET_MESSENGER_Message *msg = copy_message(message);
488
489 GNUNET_memcpy(&(msg->header.sender_id), id, sizeof(*id));
490
491 return send_srv_room_message (room, handle, msg); 341 return send_srv_room_message (room, handle, msg);
492} 342}
493 343
494static const struct GNUNET_HashCode* 344static const struct GNUNET_HashCode*
495get_next_member_session_contect(const struct GNUNET_MESSENGER_MemberSession *session) 345get_next_member_session_context(const struct GNUNET_MESSENGER_MemberSession *session)
496{ 346{
497 if (session->next) 347 if (session->next)
498 return get_next_member_session_contect (session->next); 348 return get_next_member_session_context (session->next);
499 else 349 else
500 return get_member_session_context(session); 350 return get_member_session_context(session);
501} 351}
@@ -510,23 +360,33 @@ get_handle_member_session (struct GNUNET_MESSENGER_SrvHandle *handle,
510 const struct GNUNET_ShortHashCode *id = get_srv_handle_member_id(handle, key); 360 const struct GNUNET_ShortHashCode *id = get_srv_handle_member_id(handle, key);
511 361
512 if (!id) 362 if (!id)
363 {
364 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
365 "Handle is missing a member id for its member session! (%s)\n",
366 GNUNET_h2s (key));
513 return NULL; 367 return NULL;
368 }
514 369
515 struct GNUNET_MESSENGER_MemberStore *store = get_srv_room_member_store(room); 370 struct GNUNET_MESSENGER_MemberStore *store = get_srv_room_member_store(room);
516 struct GNUNET_MESSENGER_Member *member = get_store_member(store, id); 371 struct GNUNET_MESSENGER_Member *member = get_store_member(store, id);
517 372
518 const struct GNUNET_MESSENGER_Ego *ego = get_srv_handle_ego(handle); 373 const struct GNUNET_IDENTITY_PublicKey *pubkey = get_srv_handle_key(handle);
519 374
520 if (!ego) 375 if (!pubkey)
376 {
377 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
378 "Handle is missing a public key for its member session! (%s)\n",
379 GNUNET_h2s (key));
521 return NULL; 380 return NULL;
381 }
522 382
523 return get_member_session(member, &(ego->pub)); 383 return get_member_session(member, pubkey);
524} 384}
525 385
526void 386void
527notify_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, 387notify_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle,
528 struct GNUNET_MESSENGER_SrvRoom *room, 388 struct GNUNET_MESSENGER_SrvRoom *room,
529 const struct GNUNET_MESSENGER_MemberSession *session, 389 const struct GNUNET_MESSENGER_SenderSession *session,
530 const struct GNUNET_MESSENGER_Message *message, 390 const struct GNUNET_MESSENGER_Message *message,
531 const struct GNUNET_HashCode *hash) 391 const struct GNUNET_HashCode *hash)
532{ 392{
@@ -540,30 +400,26 @@ notify_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle,
540 return; 400 return;
541 } 401 }
542 402
543 const struct GNUNET_IDENTITY_PublicKey *pubkey = get_contact_key(session->contact);
544
545 struct GNUNET_HashCode sender; 403 struct GNUNET_HashCode sender;
546 GNUNET_CRYPTO_hash(pubkey, sizeof(*pubkey), &sender); 404 const struct GNUNET_HashCode *context = NULL;
547
548 const struct GNUNET_HashCode *context = get_next_member_session_contect (session);
549 405
550 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Notifying client about message: %s\n", GNUNET_h2s (hash)); 406 if (GNUNET_YES == is_peer_message (message))
551 407 {
552 struct GNUNET_MESSENGER_Message *private_message = NULL; 408 const struct GNUNET_PeerIdentity *identity = session->peer;
409 GNUNET_CRYPTO_hash(identity, sizeof(*identity), &sender);
553 410
554 if (GNUNET_MESSENGER_KIND_PRIVATE == message->header.kind) 411 context = &sender;
412 }
413 else
555 { 414 {
556 private_message = copy_message(message); 415 const struct GNUNET_IDENTITY_PublicKey *pubkey = get_contact_key(session->member->contact);
416 GNUNET_CRYPTO_hash(pubkey, sizeof(*pubkey), &sender);
557 417
558 if (GNUNET_YES != decrypt_message(private_message, &(get_srv_handle_ego(handle)->priv))) 418 context = get_next_member_session_context (session->member);
559 {
560 destroy_message(private_message);
561 private_message = NULL;
562 }
563 else
564 message = private_message;
565 } 419 }
566 420
421 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Notifying client about message: %s\n", GNUNET_h2s (hash));
422
567 struct GNUNET_MESSENGER_RecvMessage *msg; 423 struct GNUNET_MESSENGER_RecvMessage *msg;
568 struct GNUNET_MQ_Envelope *env; 424 struct GNUNET_MQ_Envelope *env;
569 425
@@ -578,135 +434,78 @@ notify_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle,
578 434
579 msg->flags = (uint32_t) GNUNET_MESSENGER_FLAG_NONE; 435 msg->flags = (uint32_t) GNUNET_MESSENGER_FLAG_NONE;
580 436
581 if (get_handle_member_session(handle, room, key) == session) 437 if (GNUNET_YES == is_peer_message (message))
438 msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_PEER;
439 else if (get_handle_member_session(handle, room, key) == session->member)
582 msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_SENT; 440 msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_SENT;
583 441
584 if (private_message)
585 msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_PRIVATE;
586
587 char *buffer = ((char*) msg) + sizeof(*msg); 442 char *buffer = ((char*) msg) + sizeof(*msg);
588 encode_message (message, length, buffer, GNUNET_YES); 443 encode_message (message, length, buffer, GNUNET_YES);
589 444
590 if (private_message)
591 destroy_message(private_message);
592
593 GNUNET_MQ_send (handle->mq, env); 445 GNUNET_MQ_send (handle->mq, env);
594} 446}
595 447
596static int 448static int
597callback_scan_for_rooms (void *cls, 449iterate_next_member_ids (void *cls,
598 const char *filename) 450 const struct GNUNET_HashCode *key,
451 void *value)
599{ 452{
600 struct GNUNET_MESSENGER_SrvHandle *handle = cls; 453 struct GNUNET_MESSENGER_SrvHandle *handle = cls;
454 struct GNUNET_MESSENGER_NextMemberId *next = value;
601 455
602 if ((strlen(filename) <= 4) || (0 != strcmp(filename + strlen(filename) - 4, ".cfg"))) 456 struct GNUNET_MESSENGER_MemberMessage *msg;
603 return GNUNET_OK; 457 struct GNUNET_MQ_Envelope *env;
604
605 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Load room configuration of handle: %s\n", filename);
606 458
607 struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); 459 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID);
608 460
609 if ((GNUNET_YES == GNUNET_DISK_file_test (filename)) && (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, filename))) 461 GNUNET_memcpy(&(msg->key), key, sizeof(*key));
610 { 462 GNUNET_memcpy(&(msg->id), &(next->id), sizeof(next->id));
611 struct GNUNET_HashCode key; 463 msg->reset = (uint32_t) next->reset;
612 struct GNUNET_ShortHashCode member_id;
613 464
614 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_data (cfg, "room", "key", &key, sizeof(key))) && 465 GNUNET_MQ_send (handle->mq, env);
615 (GNUNET_OK == GNUNET_CONFIGURATION_get_data (cfg, "room", "member_id", &member_id, sizeof(member_id))))
616 change_srv_handle_member_id (handle, &key, &member_id);
617 }
618 466
619 GNUNET_CONFIGURATION_destroy (cfg); 467 GNUNET_free (next);
620 return GNUNET_OK; 468 return GNUNET_YES;
621} 469}
622 470
623void 471static void
624load_srv_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle) 472task_notify_srv_handle_member_id (void *cls)
625{ 473{
626 GNUNET_assert(handle); 474 struct GNUNET_MESSENGER_SrvHandle *handle = cls;
627 475 handle->notify = NULL;
628 char *id_dir;
629 get_srv_handle_data_subdir (handle, handle->name, &id_dir);
630
631 if (GNUNET_YES == GNUNET_DISK_directory_test (id_dir, GNUNET_YES))
632 {
633 char *scan_dir;
634 GNUNET_asprintf (&scan_dir, "%s%s%c", id_dir, "rooms", DIR_SEPARATOR);
635
636 if (GNUNET_OK == GNUNET_DISK_directory_test (scan_dir, GNUNET_YES))
637 GNUNET_DISK_directory_scan (scan_dir, callback_scan_for_rooms, handle);
638
639 GNUNET_free(scan_dir);
640 }
641 476
642 GNUNET_free(id_dir); 477 GNUNET_CONTAINER_multihashmap_iterate (handle->next_ids, iterate_next_member_ids, handle);
478 GNUNET_CONTAINER_multihashmap_clear (handle->next_ids);
643} 479}
644 480
645static int 481void
646iterate_save_rooms (void *cls, 482notify_srv_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle,
647 const struct GNUNET_HashCode *key, 483 struct GNUNET_MESSENGER_SrvRoom *room,
648 void *value) 484 const struct GNUNET_ShortHashCode *member_id,
485 enum GNUNET_GenericReturnValue reset)
649{ 486{
650 struct GNUNET_MESSENGER_SrvHandle *handle = cls; 487 GNUNET_assert((handle) && (room) && (member_id));
651 struct GNUNET_ShortHashCode *member_id = value;
652
653 char *id_dir;
654 get_srv_handle_data_subdir (handle, handle->name, &id_dir);
655
656 char *filename;
657 GNUNET_asprintf (&filename, "%s%s%c%s.cfg", id_dir, "rooms", DIR_SEPARATOR, GNUNET_h2s (key));
658 GNUNET_free(id_dir);
659
660 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Save room configuration of handle: %s\n", filename);
661
662 struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
663
664 char *key_data = GNUNET_STRINGS_data_to_string_alloc (key, sizeof(*key));
665 488
666 if (key_data) 489 struct GNUNET_MESSENGER_NextMemberId *next = GNUNET_new (struct GNUNET_MESSENGER_NextMemberId);
490 if (!next)
667 { 491 {
668 GNUNET_CONFIGURATION_set_value_string (cfg, "room", "key", key_data); 492 return;
669
670 GNUNET_free(key_data);
671 }
672
673 char *member_id_data = GNUNET_STRINGS_data_to_string_alloc (member_id, sizeof(*member_id));
674
675 if (member_id_data)
676 {
677 GNUNET_CONFIGURATION_set_value_string (cfg, "room", "member_id", member_id_data);
678
679 GNUNET_free(member_id_data);
680 } 493 }
681 494
682 GNUNET_CONFIGURATION_write (cfg, filename); 495 GNUNET_memcpy (&(next->id), member_id, sizeof(next->id));
683 GNUNET_CONFIGURATION_destroy (cfg); 496 next->reset = reset;
684 497
685 GNUNET_free(filename); 498 const struct GNUNET_HashCode *key = get_srv_room_key(room);
686
687 return GNUNET_YES;
688}
689
690void
691save_srv_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle)
692{
693 GNUNET_assert(handle);
694
695 char *id_dir;
696 get_srv_handle_data_subdir (handle, handle->name, &id_dir);
697 499
698 if ((GNUNET_YES == GNUNET_DISK_directory_test (id_dir, GNUNET_NO)) || (GNUNET_OK 500 struct GNUNET_MESSENGER_NextMemberId *prev = GNUNET_CONTAINER_multihashmap_get(handle->next_ids, key);
699 == GNUNET_DISK_directory_create (id_dir))) 501 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_put(handle->next_ids, key, next, GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE))
700 { 502 {
701 char *save_dir; 503 return;
702 GNUNET_asprintf (&save_dir, "%s%s%c", id_dir, "rooms", DIR_SEPARATOR);
703
704 if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) ||
705 (GNUNET_OK == GNUNET_DISK_directory_create (save_dir)))
706 GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_save_rooms, handle);
707
708 GNUNET_free(save_dir);
709 } 504 }
710 505
711 GNUNET_free(id_dir); 506 if (prev)
507 GNUNET_free (prev);
508
509 if (!handle->notify)
510 handle->notify = GNUNET_SCHEDULER_add_now (task_notify_srv_handle_member_id, handle);
712} 511}