diff options
Diffstat (limited to 'src/messenger/gnunet-service-messenger_handle.c')
-rw-r--r-- | src/messenger/gnunet-service-messenger_handle.c | 541 |
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 | ||
33 | struct GNUNET_MESSENGER_NextMemberId | ||
34 | { | ||
35 | struct GNUNET_ShortHashCode id; | ||
36 | enum GNUNET_GenericReturnValue reset; | ||
37 | }; | ||
38 | |||
34 | struct GNUNET_MESSENGER_SrvHandle* | 39 | struct GNUNET_MESSENGER_SrvHandle* |
35 | create_srv_handle (struct GNUNET_MESSENGER_Service *service, | 40 | create_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 | |||
85 | void | ||
86 | set_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); | 103 | const struct GNUNET_IDENTITY_PublicKey* |
104 | get_srv_handle_key (const struct GNUNET_MESSENGER_SrvHandle *handle) | ||
105 | { | ||
106 | GNUNET_assert(handle); | ||
107 | |||
108 | return handle->key; | ||
84 | } | 109 | } |
85 | 110 | ||
86 | void | 111 | void |
@@ -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 | |||
171 | send_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 | ||
182 | static void | 195 | struct RoomInitializationClosure |
183 | change_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 | |||
210 | static void | ||
211 | change_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 | |||
235 | struct 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 | ||
241 | static int | 202 | static int |
242 | iterate_send_message (void *cls, | 203 | find_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 | |||
253 | void | ||
254 | set_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 | ||
271 | const struct GNUNET_MESSENGER_Ego* | 212 | const struct GNUNET_IDENTITY_PublicKey *pubkey = get_srv_handle_key(init->handle); |
272 | get_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 | ||
293 | static void | 228 | change_srv_handle_member_id(init->handle, init->key, id); |
294 | callback_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 | |||
309 | void | ||
310 | setup_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 | ||
320 | static void | 232 | static void |
321 | callback_update_handle (void *cls, | 233 | initialize_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 | |||
339 | void | ||
340 | update_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 | |||
355 | static void | ||
356 | callback_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 | |||
401 | free_dirs: | ||
402 | GNUNET_free(old_dir); | ||
403 | GNUNET_free(new_dir); | ||
404 | } | ||
405 | |||
406 | void | ||
407 | set_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 | ||
427 | int | 258 | int |
@@ -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 | ||
494 | static const struct GNUNET_HashCode* | 344 | static const struct GNUNET_HashCode* |
495 | get_next_member_session_contect(const struct GNUNET_MESSENGER_MemberSession *session) | 345 | get_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 | ||
526 | void | 386 | void |
527 | notify_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, | 387 | notify_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 | ||
596 | static int | 448 | static int |
597 | callback_scan_for_rooms (void *cls, | 449 | iterate_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 | ||
623 | void | 471 | static void |
624 | load_srv_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle) | 472 | task_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 | ||
645 | static int | 481 | void |
646 | iterate_save_rooms (void *cls, | 482 | notify_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 | |||
690 | void | ||
691 | save_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 | } |