diff options
Diffstat (limited to 'src/messenger/gnunet-service-messenger_handle.c')
-rw-r--r-- | src/messenger/gnunet-service-messenger_handle.c | 449 |
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 | |||
31 | struct GNUNET_MESSENGER_SrvHandle* | 33 | struct GNUNET_MESSENGER_SrvHandle* |
32 | create_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MQ_Handle *mq) | 34 | create_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 | |||
58 | void | 59 | void |
59 | destroy_handle (struct GNUNET_MESSENGER_SrvHandle *handle) | 60 | destroy_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 | ||
76 | void | 76 | void |
77 | get_handle_data_subdir (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name, char **dir) | 77 | get_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 | |||
87 | static int | 89 | static int |
88 | create_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key) | 90 | create_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 | |||
108 | const struct GNUNET_ShortHashCode* | 114 | const struct GNUNET_ShortHashCode* |
109 | get_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key) | 115 | get_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 | ||
114 | void | 122 | int |
115 | change_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, | 123 | change_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 | |||
156 | send_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 | ||
150 | static void | 167 | static void |
151 | change_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name) | 168 | change_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 | ||
175 | static void | 194 | static void |
176 | change_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_Ego *ego) | 195 | change_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 | ||
192 | struct GNUNET_MESSENGER_Ego* | 218 | struct GNUNET_MESSENGER_MessageHandle |
193 | get_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle) | 219 | { |
220 | struct GNUNET_MESSENGER_SrvHandle *handle; | ||
221 | struct GNUNET_MESSENGER_Message *message; | ||
222 | }; | ||
223 | |||
224 | static int | ||
225 | iterate_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 | |||
234 | void | ||
235 | set_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 | |||
251 | const struct GNUNET_MESSENGER_Ego* | ||
252 | get_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 | ||
212 | void | 273 | static void |
213 | setup_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name) | 274 | callback_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 | ||
222 | struct GNUNET_MESSENGER_MessageHandle | 287 | void |
223 | { | 288 | setup_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name) |
224 | struct GNUNET_MESSENGER_SrvHandle *handle; | ||
225 | struct GNUNET_MESSENGER_Message *message; | ||
226 | }; | ||
227 | |||
228 | static int | ||
229 | iterate_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 | ||
238 | static void | 297 | static void |
239 | callback_ego_create (void *cls, const struct GNUNET_IDENTITY_PrivateKey *key, const char *emsg) | 298 | callback_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 | ||
265 | int | 312 | void |
266 | update_handle (struct GNUNET_MESSENGER_SrvHandle *handle) | 313 | update_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 | ||
284 | int | 328 | static void |
285 | set_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name) | 329 | callback_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 | |||
385 | void | ||
386 | set_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 | ||
346 | int | 405 | int |
347 | open_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key) | 406 | open_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 | |||
356 | entry_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_PeerIdentity *door, | 417 | entry_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 | |||
365 | int | 428 | int |
366 | close_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key) | 429 | close_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 | ||
374 | int | 439 | int |
375 | send_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, | 440 | send_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 | |||
468 | static const struct GNUNET_HashCode* | ||
469 | get_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 | |||
477 | void | ||
478 | notify_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 | ||
402 | static int callback_scan_for_rooms(void* cls, const char *filename) { | 539 | static int |
403 | struct GNUNET_MESSENGER_SrvHandle* handle = cls; | 540 | callback_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 | ||
422 | void load_handle_configuration(struct GNUNET_MESSENGER_SrvHandle *handle) { | 560 | void |
423 | char* id_dir; | 561 | load_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 | ||
440 | static int | 582 | static int |
441 | iterate_save_rooms(void* cls, const struct GNUNET_HashCode* key, void* value) | 583 | iterate_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 | ||
484 | void save_handle_configuration(struct GNUNET_MESSENGER_SrvHandle *handle) | 624 | void |
625 | save_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 | } |