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.c449
1 files changed, 296 insertions, 153 deletions
diff --git a/src/messenger/gnunet-service-messenger_handle.c b/src/messenger/gnunet-service-messenger_handle.c
index 38ad6fbb4..4d2318d62 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 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
@@ -28,18 +28,19 @@
28#include "gnunet-service-messenger.h" 28#include "gnunet-service-messenger.h"
29#include "gnunet-service-messenger_message_kind.h" 29#include "gnunet-service-messenger_message_kind.h"
30 30
31#include "messenger_api_util.h"
32
31struct GNUNET_MESSENGER_SrvHandle* 33struct GNUNET_MESSENGER_SrvHandle*
32create_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MQ_Handle *mq) 34create_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MQ_Handle *mq)
33{ 35{
36 GNUNET_assert((service) && (mq));
37
34 struct GNUNET_MESSENGER_SrvHandle *handle = GNUNET_new(struct GNUNET_MESSENGER_SrvHandle); 38 struct GNUNET_MESSENGER_SrvHandle *handle = GNUNET_new(struct GNUNET_MESSENGER_SrvHandle);
35 39
36 handle->service = service; 40 handle->service = service;
37 handle->mq = mq; 41 handle->mq = mq;
38 42
39 handle->name = NULL; 43 handle->name = NULL;
40
41 handle->operation = NULL;
42
43 handle->ego = NULL; 44 handle->ego = NULL;
44 45
45 handle->member_ids = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); 46 handle->member_ids = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
@@ -58,11 +59,10 @@ iterate_free_member_ids (void *cls, const struct GNUNET_HashCode *key, void *val
58void 59void
59destroy_handle (struct GNUNET_MESSENGER_SrvHandle *handle) 60destroy_handle (struct GNUNET_MESSENGER_SrvHandle *handle)
60{ 61{
61 if (handle->service->dir) 62 GNUNET_assert(handle);
62 save_handle_configuration(handle);
63 63
64 if (handle->operation) 64 if (handle->service->dir)
65 GNUNET_IDENTITY_cancel (handle->operation); 65 save_handle_configuration (handle);
66 66
67 if (handle->name) 67 if (handle->name)
68 GNUNET_free(handle->name); 68 GNUNET_free(handle->name);
@@ -74,8 +74,10 @@ destroy_handle (struct GNUNET_MESSENGER_SrvHandle *handle)
74} 74}
75 75
76void 76void
77get_handle_data_subdir (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name, char **dir) 77get_handle_data_subdir (const struct GNUNET_MESSENGER_SrvHandle *handle, const char *name, char **dir)
78{ 78{
79 GNUNET_assert((handle) && (dir));
80
79 if (name) 81 if (name)
80 GNUNET_asprintf (dir, "%s%s%c%s%c", handle->service->dir, "identities", 82 GNUNET_asprintf (dir, "%s%s%c%s%c", handle->service->dir, "identities",
81 DIR_SEPARATOR, name, DIR_SEPARATOR); 83 DIR_SEPARATOR, name, DIR_SEPARATOR);
@@ -87,11 +89,15 @@ get_handle_data_subdir (struct GNUNET_MESSENGER_SrvHandle *handle, const char *n
87static int 89static int
88create_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key) 90create_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
89{ 91{
90 struct GNUNET_ShortHashCode *random_id = generate_service_new_member_id (handle->service, key); 92 GNUNET_assert((handle) && (key));
93
94 struct GNUNET_ShortHashCode *random_id = GNUNET_new(struct GNUNET_ShortHashCode);
91 95
92 if (!random_id) 96 if (!random_id)
93 return GNUNET_NO; 97 return GNUNET_NO;
94 98
99 generate_free_member_id (random_id, NULL);
100
95 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key, random_id, 101 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key, random_id,
96 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) 102 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
97 { 103 {
@@ -99,8 +105,8 @@ create_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, const
99 return GNUNET_NO; 105 return GNUNET_NO;
100 } 106 }
101 107
102 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Created a new member id (%s) for room: %s\n", 108 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Created a new member id (%s) for room: %s\n", GNUNET_sh2s (random_id),
103 GNUNET_sh2s(random_id), GNUNET_h2s(key)); 109 GNUNET_h2s (key));
104 110
105 return GNUNET_YES; 111 return GNUNET_YES;
106} 112}
@@ -108,48 +114,61 @@ create_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, const
108const struct GNUNET_ShortHashCode* 114const struct GNUNET_ShortHashCode*
109get_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key) 115get_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
110{ 116{
117 GNUNET_assert((handle) && (key));
118
111 return GNUNET_CONTAINER_multihashmap_get (handle->member_ids, key); 119 return GNUNET_CONTAINER_multihashmap_get (handle->member_ids, key);
112} 120}
113 121
114void 122int
115change_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, 123change_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key,
116 const struct GNUNET_ShortHashCode *unique_id) 124 const struct GNUNET_ShortHashCode *unique_id)
117{ 125{
118 struct GNUNET_ShortHashCode *member_id = GNUNET_CONTAINER_multihashmap_get (handle->member_ids, key); 126 GNUNET_assert((handle) && (key) && (unique_id));
119
120 if (member_id)
121 {
122 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Changed a member id (%s) for room (%s) ",
123 GNUNET_sh2s(member_id), GNUNET_h2s(key));
124 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "into (%s).\n",
125 GNUNET_sh2s(unique_id));
126
127 GNUNET_memcpy(member_id, unique_id, sizeof(*unique_id));
128
129 struct GNUNET_MESSENGER_MemberMessage *msg;
130 struct GNUNET_MQ_Envelope *env;
131 127
132 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID); 128 struct GNUNET_ShortHashCode *member_id = GNUNET_CONTAINER_multihashmap_get (handle->member_ids, key);
133
134 GNUNET_memcpy(&(msg->key), key, sizeof(*key));
135 GNUNET_memcpy(&(msg->id), member_id, sizeof(*member_id));
136 129
137 GNUNET_MQ_send (handle->mq, env); 130 if (!member_id)
138 }
139 else
140 { 131 {
141 member_id = GNUNET_new(struct GNUNET_ShortHashCode); 132 member_id = GNUNET_new(struct GNUNET_ShortHashCode);
142 GNUNET_memcpy(member_id, unique_id, sizeof(*member_id)); 133 GNUNET_memcpy(member_id, unique_id, sizeof(*member_id));
143 134
144 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key, member_id, 135 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key, member_id,
145 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) 136 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
137 {
146 GNUNET_free(member_id); 138 GNUNET_free(member_id);
139 return GNUNET_SYSERR;
140 }
147 } 141 }
142
143 if (0 == GNUNET_memcmp(unique_id, member_id))
144 goto send_message_to_client;
145
146 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Change a member id (%s) for room (%s).\n", GNUNET_sh2s (member_id),
147 GNUNET_h2s (key));
148
149 GNUNET_memcpy(member_id, unique_id, sizeof(*unique_id));
150
151 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Member id changed to (%s).\n", GNUNET_sh2s (unique_id));
152
153 struct GNUNET_MESSENGER_MemberMessage *msg;
154 struct GNUNET_MQ_Envelope *env;
155
156send_message_to_client:
157
158 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID);
159
160 GNUNET_memcpy(&(msg->key), key, sizeof(*key));
161 GNUNET_memcpy(&(msg->id), member_id, sizeof(*member_id));
162
163 GNUNET_MQ_send (handle->mq, env);
164 return GNUNET_OK;
148} 165}
149 166
150static void 167static void
151change_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name) 168change_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name)
152{ 169{
170 GNUNET_assert(handle);
171
153 if (handle->name) 172 if (handle->name)
154 GNUNET_free(handle->name); 173 GNUNET_free(handle->name);
155 174
@@ -173,25 +192,67 @@ change_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name)
173} 192}
174 193
175static void 194static void
176change_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_Ego *ego) 195change_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_MESSENGER_Ego *ego)
177{ 196{
197 GNUNET_assert(handle);
198
178 handle->ego = ego; 199 handle->ego = ego;
179 200
180 ego = get_handle_ego(handle); 201 ego = get_handle_ego (handle);
202
203 const uint16_t length = GNUNET_IDENTITY_key_get_length(&(ego->pub));
181 204
182 struct GNUNET_MESSENGER_KeyMessage *msg; 205 struct GNUNET_MESSENGER_KeyMessage *msg;
183 struct GNUNET_MQ_Envelope *env; 206 struct GNUNET_MQ_Envelope *env;
184 207
185 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY); 208 env = GNUNET_MQ_msg_extra(msg, length, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY);
186 209
187 GNUNET_memcpy(&(msg->pubkey), &(ego->pub), sizeof(ego->pub)); 210 char *extra = ((char*) msg) + sizeof(*msg);
211
212 if (GNUNET_IDENTITY_write_key_to_buffer(&(ego->pub), extra, length) < 0)
213 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Could not write key to buffer.\n");
188 214
189 GNUNET_MQ_send (handle->mq, env); 215 GNUNET_MQ_send (handle->mq, env);
190} 216}
191 217
192struct GNUNET_MESSENGER_Ego* 218struct GNUNET_MESSENGER_MessageHandle
193get_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle) 219{
220 struct GNUNET_MESSENGER_SrvHandle *handle;
221 struct GNUNET_MESSENGER_Message *message;
222};
223
224static int
225iterate_send_message (void *cls, const struct GNUNET_HashCode *key, void *value)
226{
227 struct GNUNET_MESSENGER_MessageHandle *msg_handle = cls;
228
229 send_handle_message (msg_handle->handle, key, msg_handle->message);
230
231 return GNUNET_YES;
232}
233
234void
235set_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_MESSENGER_Ego *ego)
236{
237 GNUNET_assert((handle) && (ego));
238
239 struct GNUNET_MESSENGER_MessageHandle msg_handle;
240
241 msg_handle.handle = handle;
242 msg_handle.message = create_message_key (&(ego->priv));
243
244 GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_send_message, &msg_handle);
245
246 destroy_message (msg_handle.message);
247
248 change_handle_ego (handle, ego);
249}
250
251const struct GNUNET_MESSENGER_Ego*
252get_handle_ego (const struct GNUNET_MESSENGER_SrvHandle *handle)
194{ 253{
254 GNUNET_assert(handle);
255
195 static struct GNUNET_MESSENGER_Ego anonymous; 256 static struct GNUNET_MESSENGER_Ego anonymous;
196 static int read_keys = 0; 257 static int read_keys = 0;
197 258
@@ -200,99 +261,86 @@ get_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle)
200 261
201 if (!read_keys) 262 if (!read_keys)
202 { 263 {
203 struct GNUNET_IDENTITY_Ego* ego = GNUNET_IDENTITY_ego_get_anonymous (); 264 struct GNUNET_IDENTITY_Ego *ego = GNUNET_IDENTITY_ego_get_anonymous ();
204 GNUNET_memcpy(&(anonymous.priv), GNUNET_IDENTITY_ego_get_private_key(ego), sizeof(anonymous.priv)); 265 GNUNET_memcpy(&(anonymous.priv), GNUNET_IDENTITY_ego_get_private_key (ego), sizeof(anonymous.priv));
205 GNUNET_IDENTITY_ego_get_public_key(ego, &(anonymous.pub)); 266 GNUNET_IDENTITY_ego_get_public_key (ego, &(anonymous.pub));
206 read_keys = 1; 267 read_keys = 1;
207 } 268 }
208 269
209 return &anonymous; 270 return &anonymous;
210} 271}
211 272
212void 273static void
213setup_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name) 274callback_setup_handle_name (void *cls, const char *name, const struct GNUNET_MESSENGER_Ego *ego)
214{ 275{
276 struct GNUNET_MESSENGER_SrvHandle *handle = cls;
277
278 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Setting up handle...\n");
279
215 change_handle_name (handle, name); 280 change_handle_name (handle, name);
216 change_handle_ego (handle, handle->name? lookup_service_ego(handle->service, handle->name) : NULL); 281 change_handle_ego (handle, ego);
217 282
218 if (handle->service->dir) 283 if (handle->service->dir)
219 load_handle_configuration(handle); 284 load_handle_configuration (handle);
220} 285}
221 286
222struct GNUNET_MESSENGER_MessageHandle 287void
223{ 288setup_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name)
224 struct GNUNET_MESSENGER_SrvHandle *handle;
225 struct GNUNET_MESSENGER_Message *message;
226};
227
228static int
229iterate_send_message (void *cls, const struct GNUNET_HashCode *key, void *value)
230{ 289{
231 struct GNUNET_MESSENGER_MessageHandle *msg_handle = cls; 290 GNUNET_assert(handle);
232 291
233 send_handle_message (msg_handle->handle, key, msg_handle->message); 292 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service);
234 293
235 return GNUNET_YES; 294 lookup_store_ego (store, name, callback_setup_handle_name, handle);
236} 295}
237 296
238static void 297static void
239callback_ego_create (void *cls, const struct GNUNET_IDENTITY_PrivateKey *key, const char *emsg) 298callback_update_handle (void *cls, const char *name, const struct GNUNET_MESSENGER_Ego *ego)
240{ 299{
241 struct GNUNET_MESSENGER_SrvHandle *handle = cls; 300 struct GNUNET_MESSENGER_SrvHandle *handle = cls;
242 301
243 handle->operation = NULL; 302 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Updating handle...\n");
244 303
245 if (emsg) 304 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service);
246 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s\n", emsg);
247 305
248 if (key) 306 if (!ego)
249 { 307 create_store_ego(store, handle->name, handle);
250 struct GNUNET_MESSENGER_MessageHandle msg_handle; 308 else
251 309 change_handle_ego (handle, ego);
252 msg_handle.handle = handle;
253 msg_handle.message = create_message_key (key);
254
255 GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_send_message, &msg_handle);
256
257 destroy_message (msg_handle.message);
258
259 update_service_ego(handle->service, handle->name, key);
260
261 change_handle_ego (handle, lookup_service_ego(handle->service, handle->name));
262 }
263} 310}
264 311
265int 312void
266update_handle (struct GNUNET_MESSENGER_SrvHandle *handle) 313update_handle (struct GNUNET_MESSENGER_SrvHandle *handle)
267{ 314{
268 GNUNET_assert(handle); 315 GNUNET_assert(handle);
269 316
270 if (!handle->name) 317 if (!handle->name)
271 return GNUNET_SYSERR; 318 {
272 319 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Updating handle failed: Name is required!\n");
273 struct GNUNET_MESSENGER_Ego *ego = lookup_service_ego(handle->service, handle->name); 320 return;
321 }
274 322
275 if (!ego) 323 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service);
276 handle->operation = GNUNET_IDENTITY_create (handle->service->identity, handle->name, NULL,
277 GNUNET_IDENTITY_TYPE_ECDSA, callback_ego_create, handle);
278 else
279 change_handle_ego (handle, ego);
280 324
281 return GNUNET_OK; 325 lookup_store_ego (store, handle->name, callback_update_handle, handle);
282} 326}
283 327
284int 328static void
285set_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name) 329callback_set_handle_name (void *cls, const char *name, const struct GNUNET_MESSENGER_Ego *ego)
286{ 330{
287 GNUNET_assert(handle); 331 struct GNUNET_MESSENGER_SrvHandle *handle = cls;
288 332
289 if ((name) && (lookup_service_ego(handle->service, name))) 333 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Renaming handle...\n");
290 return GNUNET_NO; 334
335 if (ego)
336 {
337 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Renaming handle failed: Name is occupied! (%s)\n", name);
338 return;
339 }
291 340
292 struct GNUNET_IDENTITY_Operation *operation = handle->operation; 341 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service);
293 342
294 if (handle->name) 343 int rename_ego_in_store = handle->ego? GNUNET_YES : GNUNET_NO;
295 handle->operation = GNUNET_IDENTITY_rename (handle->service->identity, handle->name, name, NULL, NULL);
296 344
297 char *old_dir; 345 char *old_dir;
298 get_handle_data_subdir (handle, handle->name, &old_dir); 346 get_handle_data_subdir (handle, handle->name, &old_dir);
@@ -323,29 +371,42 @@ set_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name)
323 destroy_message (msg_handle.message); 371 destroy_message (msg_handle.message);
324 372
325 change_handle_name (handle, name); 373 change_handle_name (handle, name);
326
327 if (operation)
328 GNUNET_IDENTITY_cancel (operation);
329 } 374 }
330 else 375 else
376 rename_ego_in_store = GNUNET_NO;
377
378 GNUNET_free(old_dir);
379 GNUNET_free(new_dir);
380
381 if (GNUNET_YES == rename_ego_in_store)
382 rename_store_ego(store, handle->name, name);
383}
384
385void
386set_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name)
387{
388 GNUNET_assert(handle);
389
390 if (!name)
331 { 391 {
332 if (handle->operation) 392 if (handle->ego)
333 { 393 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Renaming handle failed: Name is required!\n");
334 GNUNET_IDENTITY_cancel (handle->operation); 394 else
395 change_handle_name (handle, name);
335 396
336 handle->operation = operation; 397 return;
337 }
338 } 398 }
339 399
340 GNUNET_free(old_dir); 400 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service);
341 GNUNET_free(new_dir);
342 401
343 return (result == 0 ? GNUNET_OK : GNUNET_NO); 402 lookup_store_ego (store, name, callback_set_handle_name, handle);
344} 403}
345 404
346int 405int
347open_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key) 406open_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
348{ 407{
408 GNUNET_assert((handle) && (key));
409
349 if ((!get_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key))) 410 if ((!get_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key)))
350 return GNUNET_NO; 411 return GNUNET_NO;
351 412
@@ -356,6 +417,8 @@ int
356entry_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_PeerIdentity *door, 417entry_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_PeerIdentity *door,
357 const struct GNUNET_HashCode *key) 418 const struct GNUNET_HashCode *key)
358{ 419{
420 GNUNET_assert((handle) && (door) && (key));
421
359 if ((!get_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key))) 422 if ((!get_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key)))
360 return GNUNET_NO; 423 return GNUNET_NO;
361 424
@@ -365,6 +428,8 @@ entry_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNE
365int 428int
366close_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key) 429close_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
367{ 430{
431 GNUNET_assert((handle) && (key));
432
368 if (!get_handle_member_id (handle, key)) 433 if (!get_handle_member_id (handle, key))
369 return GNUNET_NO; 434 return GNUNET_NO;
370 435
@@ -373,8 +438,10 @@ close_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNE
373 438
374int 439int
375send_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, 440send_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key,
376 struct GNUNET_MESSENGER_Message *message) 441 const struct GNUNET_MESSENGER_Message *message)
377{ 442{
443 GNUNET_assert((handle) && (key) && (message));
444
378 const struct GNUNET_ShortHashCode *id = get_handle_member_id (handle, key); 445 const struct GNUNET_ShortHashCode *id = get_handle_member_id (handle, key);
379 446
380 if (!id) 447 if (!id)
@@ -391,45 +458,120 @@ send_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNU
391 return GNUNET_NO; 458 return GNUNET_NO;
392 } 459 }
393 460
394 struct GNUNET_HashCode hash; 461 struct GNUNET_MESSENGER_Message *msg = copy_message(message);
395 462
396 GNUNET_memcpy(&(message->header.sender_id), id, sizeof(*id)); 463 GNUNET_memcpy(&(msg->header.sender_id), id, sizeof(*id));
397 464
398 send_room_message (room, handle, message, &hash); 465 return send_room_message (room, handle, msg);
399 return GNUNET_YES; 466}
467
468static const struct GNUNET_HashCode*
469get_next_member_session_contect(const struct GNUNET_MESSENGER_MemberSession *session)
470{
471 if (session->next)
472 return get_next_member_session_contect (session->next);
473 else
474 return get_member_session_context(session);
475}
476
477void
478notify_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key,
479 const struct GNUNET_MESSENGER_MemberSession *session,
480 const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
481{
482 GNUNET_assert((handle) && (key) && (session) && (message) && (hash));
483
484 if ((!handle->mq) || (!get_handle_member_id (handle, key)))
485 {
486 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Notifying client about message requires membership!\n");
487 return;
488 }
489
490 const struct GNUNET_IDENTITY_PublicKey *pubkey = get_contact_key(session->contact);
491
492 struct GNUNET_HashCode sender;
493 GNUNET_CRYPTO_hash(pubkey, sizeof(*pubkey), &sender);
494
495 const struct GNUNET_HashCode *context = get_next_member_session_contect (session);
496
497 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Notifying client about message: %s\n", GNUNET_h2s (hash));
498
499 struct GNUNET_MESSENGER_Message *private_message = NULL;
500
501 if (GNUNET_MESSENGER_KIND_PRIVATE == message->header.kind)
502 {
503 private_message = copy_message(message);
504
505 if (GNUNET_YES != decrypt_message(private_message, &(get_handle_ego(handle)->priv)))
506 {
507 destroy_message(private_message);
508 private_message = NULL;
509 }
510 else
511 message = private_message;
512 }
513
514 struct GNUNET_MESSENGER_RecvMessage *msg;
515 struct GNUNET_MQ_Envelope *env;
516
517 uint16_t length = get_message_size (message, GNUNET_YES);
518
519 env = GNUNET_MQ_msg_extra(msg, length, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE);
520
521 GNUNET_memcpy(&(msg->key), key, sizeof(msg->key));
522 GNUNET_memcpy(&(msg->sender), &sender, sizeof(msg->sender));
523 GNUNET_memcpy(&(msg->context), context, sizeof(msg->context));
524 GNUNET_memcpy(&(msg->hash), hash, sizeof(msg->hash));
525
526 msg->flags = (uint32_t) (
527 private_message? GNUNET_MESSENGER_FLAG_PRIVATE : GNUNET_MESSENGER_FLAG_NONE
528 );
529
530 char *buffer = ((char*) msg) + sizeof(*msg);
531 encode_message (message, length, buffer, GNUNET_YES);
532
533 if (private_message)
534 destroy_message(private_message);
535
536 GNUNET_MQ_send (handle->mq, env);
400} 537}
401 538
402static int callback_scan_for_rooms(void* cls, const char *filename) { 539static int
403 struct GNUNET_MESSENGER_SrvHandle* handle = cls; 540callback_scan_for_rooms (void *cls, const char *filename)
541{
542 struct GNUNET_MESSENGER_SrvHandle *handle = cls;
404 543
405 struct GNUNET_CONFIGURATION_Handle* cfg = GNUNET_CONFIGURATION_create(); 544 struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
406 545
407 if ((GNUNET_YES == GNUNET_DISK_file_test(filename)) && 546 if ((GNUNET_YES == GNUNET_DISK_file_test (filename)) && (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, filename)))
408 (GNUNET_OK == GNUNET_CONFIGURATION_parse(cfg, filename)))
409 { 547 {
410 struct GNUNET_HashCode key; 548 struct GNUNET_HashCode key;
411 struct GNUNET_ShortHashCode member_id; 549 struct GNUNET_ShortHashCode member_id;
412 550
413 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_data(cfg, "room", "key", &key, sizeof(key))) && 551 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_data (cfg, "room", "key", &key, sizeof(key))) &&
414 (GNUNET_OK == GNUNET_CONFIGURATION_get_data(cfg, "room", "member_id", &member_id, sizeof(member_id)))) 552 (GNUNET_OK == GNUNET_CONFIGURATION_get_data (cfg, "room", "member_id", &member_id, sizeof(member_id))))
415 change_handle_member_id(handle, &key, &member_id); 553 change_handle_member_id (handle, &key, &member_id);
416 } 554 }
417 555
418 GNUNET_CONFIGURATION_destroy(cfg); 556 GNUNET_CONFIGURATION_destroy (cfg);
419 return GNUNET_OK; 557 return GNUNET_OK;
420} 558}
421 559
422void load_handle_configuration(struct GNUNET_MESSENGER_SrvHandle *handle) { 560void
423 char* id_dir; 561load_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle)
424 get_handle_data_subdir(handle, handle->name, &id_dir); 562{
563 GNUNET_assert(handle);
425 564
426 if (GNUNET_YES == GNUNET_DISK_directory_test(id_dir, GNUNET_YES)) 565 char *id_dir;
566 get_handle_data_subdir (handle, handle->name, &id_dir);
567
568 if (GNUNET_YES == GNUNET_DISK_directory_test (id_dir, GNUNET_YES))
427 { 569 {
428 char* scan_dir; 570 char *scan_dir;
429 GNUNET_asprintf(&scan_dir, "%s%s%c", id_dir, "rooms", DIR_SEPARATOR); 571 GNUNET_asprintf (&scan_dir, "%s%s%c", id_dir, "rooms", DIR_SEPARATOR);
430 572
431 if (GNUNET_OK == GNUNET_DISK_directory_test(scan_dir, GNUNET_YES)) 573 if (GNUNET_OK == GNUNET_DISK_directory_test (scan_dir, GNUNET_YES))
432 GNUNET_DISK_directory_scan(scan_dir, callback_scan_for_rooms, handle); 574 GNUNET_DISK_directory_scan (scan_dir, callback_scan_for_rooms, handle);
433 575
434 GNUNET_free(scan_dir); 576 GNUNET_free(scan_dir);
435 } 577 }
@@ -438,63 +580,64 @@ void load_handle_configuration(struct GNUNET_MESSENGER_SrvHandle *handle) {
438} 580}
439 581
440static int 582static int
441iterate_save_rooms(void* cls, const struct GNUNET_HashCode* key, void* value) 583iterate_save_rooms (void *cls, const struct GNUNET_HashCode *key, void *value)
442{ 584{
443 struct GNUNET_MESSENGER_SrvHandle* handle = cls; 585 struct GNUNET_MESSENGER_SrvHandle *handle = cls;
444 struct GNUNET_ShortHashCode* member_id = value; 586 struct GNUNET_ShortHashCode *member_id = value;
445 587
446 char* id_dir; 588 char *id_dir;
447 get_handle_data_subdir(handle, handle->name, &id_dir); 589 get_handle_data_subdir (handle, handle->name, &id_dir);
448 590
449 char* filename; 591 char *filename;
450 GNUNET_asprintf(&filename, "%s%s%c%s.cfg", 592 GNUNET_asprintf (&filename, "%s%s%c%s.cfg", id_dir, "rooms", DIR_SEPARATOR, GNUNET_h2s (key));
451 id_dir, "rooms", DIR_SEPARATOR,
452 GNUNET_h2s(key));
453 593
454 GNUNET_free(id_dir); 594 GNUNET_free(id_dir);
455 595
456 struct GNUNET_CONFIGURATION_Handle* cfg = GNUNET_CONFIGURATION_create(); 596 struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
457 597
458 char* key_data = GNUNET_STRINGS_data_to_string_alloc(key, sizeof(*key)); 598 char *key_data = GNUNET_STRINGS_data_to_string_alloc (key, sizeof(*key));
459 599
460 if (key_data) 600 if (key_data)
461 { 601 {
462 GNUNET_CONFIGURATION_set_value_string(cfg, "room", "key", key_data); 602 GNUNET_CONFIGURATION_set_value_string (cfg, "room", "key", key_data);
463 603
464 GNUNET_free(key_data); 604 GNUNET_free(key_data);
465 } 605 }
466 606
467 char* member_id_data = GNUNET_STRINGS_data_to_string_alloc(member_id, sizeof(*member_id)); 607 char *member_id_data = GNUNET_STRINGS_data_to_string_alloc (member_id, sizeof(*member_id));
468 608
469 if (member_id_data) 609 if (member_id_data)
470 { 610 {
471 GNUNET_CONFIGURATION_set_value_string(cfg, "room", "member_id", member_id_data); 611 GNUNET_CONFIGURATION_set_value_string (cfg, "room", "member_id", member_id_data);
472 612
473 GNUNET_free(member_id_data); 613 GNUNET_free(member_id_data);
474 } 614 }
475 615
476 GNUNET_CONFIGURATION_write(cfg, filename); 616 GNUNET_CONFIGURATION_write (cfg, filename);
477 GNUNET_CONFIGURATION_destroy(cfg); 617 GNUNET_CONFIGURATION_destroy (cfg);
478 618
479 GNUNET_free(filename); 619 GNUNET_free(filename);
480 620
481 return GNUNET_YES; 621 return GNUNET_YES;
482} 622}
483 623
484void save_handle_configuration(struct GNUNET_MESSENGER_SrvHandle *handle) 624void
625save_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle)
485{ 626{
486 char* id_dir; 627 GNUNET_assert(handle);
487 get_handle_data_subdir(handle, handle->name, &id_dir); 628
629 char *id_dir;
630 get_handle_data_subdir (handle, handle->name, &id_dir);
488 631
489 if ((GNUNET_YES == GNUNET_DISK_directory_test(id_dir, GNUNET_NO)) || 632 if ((GNUNET_YES == GNUNET_DISK_directory_test (id_dir, GNUNET_NO)) || (GNUNET_OK
490 (GNUNET_OK == GNUNET_DISK_directory_create(id_dir))) 633 == GNUNET_DISK_directory_create (id_dir)))
491 { 634 {
492 char* save_dir; 635 char *save_dir;
493 GNUNET_asprintf(&save_dir, "%s%s%c", id_dir, "rooms", DIR_SEPARATOR); 636 GNUNET_asprintf (&save_dir, "%s%s%c", id_dir, "rooms", DIR_SEPARATOR);
494 637
495 if ((GNUNET_YES == GNUNET_DISK_directory_test(save_dir, GNUNET_NO)) || 638 if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) ||
496 (GNUNET_OK == GNUNET_DISK_directory_create(save_dir))) 639 (GNUNET_OK == GNUNET_DISK_directory_create (save_dir)))
497 GNUNET_CONTAINER_multihashmap_iterate(handle->member_ids, iterate_save_rooms, handle); 640 GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_save_rooms, handle);
498 641
499 GNUNET_free(save_dir); 642 GNUNET_free(save_dir);
500 } 643 }