diff options
Diffstat (limited to 'src/service/messenger/gnunet-service-messenger_handle.c')
-rw-r--r-- | src/service/messenger/gnunet-service-messenger_handle.c | 705 |
1 files changed, 258 insertions, 447 deletions
diff --git a/src/service/messenger/gnunet-service-messenger_handle.c b/src/service/messenger/gnunet-service-messenger_handle.c index 764331c4a..4f15ad2f3 100644 --- a/src/service/messenger/gnunet-service-messenger_handle.c +++ b/src/service/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,68 +27,101 @@ | |||
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) |
37 | { | 42 | { |
38 | GNUNET_assert((service) && (mq)); | 43 | GNUNET_assert ((service) && (mq)); |
39 | 44 | ||
40 | struct GNUNET_MESSENGER_SrvHandle *handle = GNUNET_new(struct GNUNET_MESSENGER_SrvHandle); | 45 | struct GNUNET_MESSENGER_SrvHandle *handle = GNUNET_new (struct |
46 | GNUNET_MESSENGER_SrvHandle); | ||
41 | 47 | ||
42 | handle->service = service; | 48 | handle->service = service; |
43 | handle->mq = mq; | 49 | handle->mq = mq; |
44 | 50 | ||
45 | handle->name = NULL; | ||
46 | handle->ego = NULL; | ||
47 | |||
48 | handle->member_ids = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); | 51 | handle->member_ids = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); |
52 | handle->next_ids = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO); | ||
53 | |||
54 | handle->notify = NULL; | ||
49 | 55 | ||
50 | return handle; | 56 | return handle; |
51 | } | 57 | } |
52 | 58 | ||
59 | |||
53 | int | 60 | int |
54 | iterate_free_member_ids (void *cls, | 61 | iterate_free_member_ids (void *cls, |
55 | const struct GNUNET_HashCode *key, | 62 | const struct GNUNET_HashCode *key, |
56 | void *value) | 63 | void *value) |
57 | { | 64 | { |
58 | GNUNET_free(value); | 65 | GNUNET_free (value); |
59 | 66 | ||
60 | return GNUNET_YES; | 67 | return GNUNET_YES; |
61 | } | 68 | } |
62 | 69 | ||
70 | |||
63 | void | 71 | void |
64 | destroy_srv_handle (struct GNUNET_MESSENGER_SrvHandle *handle) | 72 | destroy_srv_handle (struct GNUNET_MESSENGER_SrvHandle *handle) |
65 | { | 73 | { |
66 | GNUNET_assert(handle); | 74 | GNUNET_assert (handle); |
67 | 75 | ||
68 | if (handle->service->dir) | 76 | if (handle->notify) |
69 | save_srv_handle_configuration (handle); | 77 | GNUNET_SCHEDULER_cancel (handle->notify); |
70 | 78 | ||
71 | if (handle->name) | 79 | GNUNET_CONTAINER_multihashmap_iterate (handle->next_ids, |
72 | { | 80 | iterate_free_member_ids, NULL); |
73 | struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service); | 81 | GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, |
82 | iterate_free_member_ids, NULL); | ||
83 | |||
84 | GNUNET_CONTAINER_multihashmap_destroy (handle->next_ids); | ||
85 | GNUNET_CONTAINER_multihashmap_destroy (handle->member_ids); | ||
86 | |||
87 | GNUNET_free (handle); | ||
88 | } | ||
74 | 89 | ||
75 | unbind_store_ego(store, handle->name, handle); | ||
76 | 90 | ||
77 | GNUNET_free(handle->name); | 91 | void |
92 | set_srv_handle_key (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
93 | const struct GNUNET_CRYPTO_PublicKey *key) | ||
94 | { | ||
95 | GNUNET_assert (handle); | ||
96 | |||
97 | if ((handle->key) && (! key)) | ||
98 | { | ||
99 | GNUNET_free (handle->key); | ||
100 | handle->key = NULL; | ||
78 | } | 101 | } |
102 | else if (! handle->key) | ||
103 | handle->key = GNUNET_new (struct GNUNET_CRYPTO_PublicKey); | ||
104 | |||
105 | if (key) | ||
106 | memcpy (handle->key, key, sizeof(struct GNUNET_CRYPTO_PublicKey)); | ||
107 | } | ||
79 | 108 | ||
80 | GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_free_member_ids, NULL); | ||
81 | GNUNET_CONTAINER_multihashmap_destroy (handle->member_ids); | ||
82 | 109 | ||
83 | GNUNET_free(handle); | 110 | const struct GNUNET_CRYPTO_PublicKey* |
111 | get_srv_handle_key (const struct GNUNET_MESSENGER_SrvHandle *handle) | ||
112 | { | ||
113 | GNUNET_assert (handle); | ||
114 | |||
115 | return handle->key; | ||
84 | } | 116 | } |
85 | 117 | ||
118 | |||
86 | void | 119 | void |
87 | get_srv_handle_data_subdir (const struct GNUNET_MESSENGER_SrvHandle *handle, | 120 | get_srv_handle_data_subdir (const struct GNUNET_MESSENGER_SrvHandle *handle, |
88 | const char *name, | 121 | const char *name, |
89 | char **dir) | 122 | char **dir) |
90 | { | 123 | { |
91 | GNUNET_assert((handle) && (dir)); | 124 | GNUNET_assert ((handle) && (dir)); |
92 | 125 | ||
93 | if (name) | 126 | if (name) |
94 | GNUNET_asprintf (dir, "%s%s%c%s%c", handle->service->dir, "identities", | 127 | GNUNET_asprintf (dir, "%s%s%c%s%c", handle->service->dir, "identities", |
@@ -98,615 +131,393 @@ get_srv_handle_data_subdir (const struct GNUNET_MESSENGER_SrvHandle *handle, | |||
98 | DIR_SEPARATOR); | 131 | DIR_SEPARATOR); |
99 | } | 132 | } |
100 | 133 | ||
134 | |||
101 | static int | 135 | static int |
102 | create_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, | 136 | create_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, |
103 | const struct GNUNET_HashCode *key) | 137 | const struct GNUNET_HashCode *key) |
104 | { | 138 | { |
105 | GNUNET_assert((handle) && (key)); | 139 | GNUNET_assert ((handle) && (key)); |
106 | 140 | ||
107 | struct GNUNET_ShortHashCode *random_id = GNUNET_new(struct GNUNET_ShortHashCode); | 141 | struct GNUNET_ShortHashCode *random_id = GNUNET_new (struct |
142 | GNUNET_ShortHashCode); | ||
108 | 143 | ||
109 | if (!random_id) | 144 | if (! random_id) |
110 | return GNUNET_NO; | 145 | return GNUNET_NO; |
111 | 146 | ||
112 | generate_free_member_id (random_id, NULL); | 147 | generate_free_member_id (random_id, NULL); |
113 | 148 | ||
114 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key, random_id, | 149 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key, |
150 | random_id, | ||
115 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | 151 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) |
116 | { | 152 | { |
117 | GNUNET_free(random_id); | 153 | GNUNET_free (random_id); |
118 | return GNUNET_NO; | 154 | return GNUNET_NO; |
119 | } | 155 | } |
120 | 156 | ||
121 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Created a new member id (%s) for room: %s\n", GNUNET_sh2s (random_id), | 157 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
122 | GNUNET_h2s (key)); | 158 | "Created a new member id (%s) for room: %s\n", GNUNET_sh2s ( |
159 | random_id), | ||
160 | GNUNET_h2s (key)); | ||
123 | 161 | ||
124 | return GNUNET_YES; | 162 | return GNUNET_YES; |
125 | } | 163 | } |
126 | 164 | ||
165 | |||
127 | const struct GNUNET_ShortHashCode* | 166 | const struct GNUNET_ShortHashCode* |
128 | get_srv_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, | 167 | get_srv_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, |
129 | const struct GNUNET_HashCode *key) | 168 | const struct GNUNET_HashCode *key) |
130 | { | 169 | { |
131 | GNUNET_assert((handle) && (key)); | 170 | GNUNET_assert ((handle) && (key)); |
132 | 171 | ||
133 | return GNUNET_CONTAINER_multihashmap_get (handle->member_ids, key); | 172 | return GNUNET_CONTAINER_multihashmap_get (handle->member_ids, key); |
134 | } | 173 | } |
135 | 174 | ||
175 | |||
136 | int | 176 | int |
137 | change_srv_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle, | 177 | change_srv_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle, |
138 | const struct GNUNET_HashCode *key, | 178 | const struct GNUNET_HashCode *key, |
139 | const struct GNUNET_ShortHashCode *unique_id) | 179 | const struct GNUNET_ShortHashCode *unique_id) |
140 | { | 180 | { |
141 | GNUNET_assert((handle) && (key) && (unique_id)); | 181 | GNUNET_assert ((handle) && (key) && (unique_id)); |
142 | 182 | ||
143 | struct GNUNET_ShortHashCode *member_id = GNUNET_CONTAINER_multihashmap_get (handle->member_ids, key); | 183 | struct GNUNET_ShortHashCode *member_id = GNUNET_CONTAINER_multihashmap_get ( |
184 | handle->member_ids, key); | ||
144 | 185 | ||
145 | if (!member_id) | 186 | if (! member_id) |
146 | { | 187 | { |
147 | member_id = GNUNET_new(struct GNUNET_ShortHashCode); | 188 | member_id = GNUNET_new (struct GNUNET_ShortHashCode); |
148 | GNUNET_memcpy(member_id, unique_id, sizeof(*member_id)); | 189 | GNUNET_memcpy (member_id, unique_id, sizeof(*member_id)); |
149 | 190 | ||
150 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key, member_id, | 191 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key, |
192 | member_id, | ||
151 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | 193 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) |
152 | { | 194 | { |
153 | GNUNET_free(member_id); | 195 | GNUNET_free (member_id); |
154 | return GNUNET_SYSERR; | 196 | return GNUNET_SYSERR; |
155 | } | 197 | } |
156 | } | 198 | } |
157 | 199 | ||
158 | if (0 == GNUNET_memcmp(unique_id, member_id)) | 200 | if (0 == GNUNET_memcmp (unique_id, member_id)) |
159 | goto send_message_to_client; | 201 | return GNUNET_OK; |
160 | |||
161 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Change a member id (%s) for room (%s).\n", GNUNET_sh2s (member_id), | ||
162 | GNUNET_h2s (key)); | ||
163 | |||
164 | GNUNET_memcpy(member_id, unique_id, sizeof(*unique_id)); | ||
165 | |||
166 | 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 | 202 | ||
173 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID); | 203 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
204 | "Change a member id (%s) for room (%s).\n", GNUNET_sh2s ( | ||
205 | member_id), | ||
206 | GNUNET_h2s (key)); | ||
174 | 207 | ||
175 | GNUNET_memcpy(&(msg->key), key, sizeof(*key)); | 208 | GNUNET_memcpy (member_id, unique_id, sizeof(*unique_id)); |
176 | GNUNET_memcpy(&(msg->id), member_id, sizeof(*member_id)); | ||
177 | 209 | ||
178 | GNUNET_MQ_send (handle->mq, env); | 210 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Member id changed to (%s).\n", |
211 | GNUNET_sh2s (unique_id)); | ||
179 | return GNUNET_OK; | 212 | return GNUNET_OK; |
180 | } | 213 | } |
181 | 214 | ||
182 | static void | ||
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 | 215 | ||
200 | char *extra = ((char*) msg) + sizeof(*msg); | 216 | int |
201 | 217 | open_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, | |
202 | if (name_len) | 218 | const struct GNUNET_HashCode *key) |
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 | { | 219 | { |
214 | GNUNET_assert(handle); | 220 | GNUNET_assert ((handle) && (key)); |
215 | |||
216 | handle->ego = ego; | ||
217 | |||
218 | ego = get_srv_handle_ego (handle); | ||
219 | |||
220 | const uint16_t length = GNUNET_CRYPTO_public_key_get_length(&(ego->pub)); | ||
221 | |||
222 | struct GNUNET_MESSENGER_KeyMessage *msg; | ||
223 | struct GNUNET_MQ_Envelope *env; | ||
224 | 221 | ||
225 | env = GNUNET_MQ_msg_extra(msg, length, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY); | 222 | if ((! get_srv_handle_member_id (handle, key)) && (GNUNET_YES != |
226 | 223 | create_handle_member_id ( | |
227 | char *extra = ((char*) msg) + sizeof(*msg); | 224 | handle, key))) |
228 | 225 | return GNUNET_NO; | |
229 | if (GNUNET_CRYPTO_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 | 226 | ||
232 | GNUNET_MQ_send (handle->mq, env); | 227 | return open_service_room (handle->service, handle, key); |
233 | } | 228 | } |
234 | 229 | ||
235 | struct GNUNET_MESSENGER_MessageHandle | ||
236 | { | ||
237 | struct GNUNET_MESSENGER_SrvHandle *handle; | ||
238 | struct GNUNET_MESSENGER_Message *message; | ||
239 | }; | ||
240 | 230 | ||
241 | static int | 231 | int |
242 | iterate_send_message (void *cls, | 232 | entry_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, |
243 | const struct GNUNET_HashCode *key, | 233 | const struct GNUNET_PeerIdentity *door, |
244 | void *value) | 234 | const struct GNUNET_HashCode *key) |
245 | { | 235 | { |
246 | struct GNUNET_MESSENGER_MessageHandle *msg_handle = cls; | 236 | GNUNET_assert ((handle) && (door) && (key)); |
247 | 237 | ||
248 | send_srv_handle_message (msg_handle->handle, key, msg_handle->message); | 238 | if ((! get_srv_handle_member_id (handle, key)) && (GNUNET_YES != |
239 | create_handle_member_id ( | ||
240 | handle, key))) | ||
241 | return GNUNET_NO; | ||
249 | 242 | ||
250 | return GNUNET_YES; | 243 | return entry_service_room (handle->service, handle, door, key); |
251 | } | 244 | } |
252 | 245 | ||
253 | void | ||
254 | set_srv_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
255 | const struct GNUNET_MESSENGER_Ego *ego) | ||
256 | { | ||
257 | GNUNET_assert((handle) && (ego)); | ||
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 | 246 | ||
266 | destroy_message (msg_handle.message); | 247 | int |
267 | 248 | close_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, | |
268 | change_handle_ego (handle, ego); | 249 | const struct GNUNET_HashCode *key) |
269 | } | ||
270 | |||
271 | const struct GNUNET_MESSENGER_Ego* | ||
272 | get_srv_handle_ego (const struct GNUNET_MESSENGER_SrvHandle *handle) | ||
273 | { | 250 | { |
274 | GNUNET_assert(handle); | 251 | GNUNET_assert ((handle) && (key)); |
275 | 252 | ||
276 | static struct GNUNET_MESSENGER_Ego anonymous; | 253 | GNUNET_CONTAINER_multihashmap_get_multiple (handle->next_ids, key, |
277 | static int read_keys = 0; | 254 | iterate_free_member_ids, NULL); |
255 | GNUNET_CONTAINER_multihashmap_remove_all (handle->next_ids, key); | ||
278 | 256 | ||
279 | if (handle->ego) | 257 | if ((handle->notify) && (0 == GNUNET_CONTAINER_multihashmap_size ( |
280 | return handle->ego; | 258 | handle->next_ids))) |
281 | |||
282 | if (!read_keys) | ||
283 | { | 259 | { |
284 | struct GNUNET_IDENTITY_Ego *ego = GNUNET_IDENTITY_ego_get_anonymous (); | 260 | GNUNET_SCHEDULER_cancel (handle->notify); |
285 | GNUNET_memcpy(&(anonymous.priv), GNUNET_IDENTITY_ego_get_private_key (ego), sizeof(anonymous.priv)); | 261 | handle->notify = NULL; |
286 | GNUNET_IDENTITY_ego_get_public_key (ego, &(anonymous.pub)); | ||
287 | read_keys = 1; | ||
288 | } | 262 | } |
289 | 263 | ||
290 | return &anonymous; | 264 | if (! get_srv_handle_member_id (handle, key)) |
291 | } | 265 | return GNUNET_NO; |
292 | |||
293 | static void | ||
294 | callback_setup_handle_name (void *cls, | ||
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 | 266 | ||
317 | lookup_store_ego (store, name, callback_setup_handle_name, handle); | 267 | return close_service_room (handle->service, handle, key); |
318 | } | 268 | } |
319 | 269 | ||
320 | static void | ||
321 | callback_update_handle (void *cls, | ||
322 | const char *name, | ||
323 | const struct GNUNET_MESSENGER_Ego *ego) | ||
324 | { | ||
325 | struct GNUNET_MESSENGER_SrvHandle *handle = cls; | ||
326 | |||
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 | 270 | ||
339 | void | 271 | void |
340 | update_srv_handle (struct GNUNET_MESSENGER_SrvHandle *handle) | 272 | sync_srv_handle_messages (struct GNUNET_MESSENGER_SrvHandle *handle, |
341 | { | 273 | const struct GNUNET_HashCode *key, |
342 | GNUNET_assert (handle); | 274 | const struct GNUNET_HashCode *prev, |
343 | 275 | struct GNUNET_HashCode *hash) | |
344 | if (!handle->name) | ||
345 | { | ||
346 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Updating handle failed: Name is required!\n"); | ||
347 | return; | ||
348 | } | ||
349 | |||
350 | struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service); | ||
351 | |||
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 | { | 276 | { |
360 | struct GNUNET_MESSENGER_SrvHandle *handle = cls; | 277 | GNUNET_assert ((handle) && (key) && (prev) && (hash)); |
361 | 278 | ||
362 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Renaming handle...\n"); | 279 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (handle->service, |
280 | key); | ||
363 | 281 | ||
364 | if (ego) | 282 | if ((! room) || (! get_srv_handle_member_id (handle, key))) |
365 | { | 283 | { |
366 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Renaming handle failed: Name is occupied! (%s)\n", name); | 284 | GNUNET_memcpy (hash, prev, sizeof(*hash)); |
367 | return; | 285 | return; |
368 | } | 286 | } |
369 | 287 | ||
370 | struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service); | 288 | merge_srv_room_last_messages (room, handle); |
371 | 289 | get_message_state_chain_hash (&(room->state), hash); | |
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 | } | 290 | } |
405 | 291 | ||
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 | |||
419 | return; | ||
420 | } | ||
421 | |||
422 | struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service); | ||
423 | |||
424 | lookup_store_ego (store, name, callback_set_handle_name, handle); | ||
425 | } | ||
426 | |||
427 | int | ||
428 | open_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
429 | const struct GNUNET_HashCode *key) | ||
430 | { | ||
431 | GNUNET_assert((handle) && (key)); | ||
432 | |||
433 | if ((!get_srv_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key))) | ||
434 | return GNUNET_NO; | ||
435 | |||
436 | return open_service_room (handle->service, handle, key); | ||
437 | } | ||
438 | |||
439 | int | ||
440 | entry_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
441 | const struct GNUNET_PeerIdentity *door, | ||
442 | const struct GNUNET_HashCode *key) | ||
443 | { | ||
444 | GNUNET_assert((handle) && (door) && (key)); | ||
445 | |||
446 | if ((!get_srv_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key))) | ||
447 | return GNUNET_NO; | ||
448 | |||
449 | return entry_service_room (handle->service, handle, door, key); | ||
450 | } | ||
451 | |||
452 | int | ||
453 | close_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
454 | const struct GNUNET_HashCode *key) | ||
455 | { | ||
456 | GNUNET_assert((handle) && (key)); | ||
457 | |||
458 | if (!get_srv_handle_member_id (handle, key)) | ||
459 | return GNUNET_NO; | ||
460 | |||
461 | return close_service_room (handle->service, handle, key); | ||
462 | } | ||
463 | 292 | ||
464 | int | 293 | int |
465 | send_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, | 294 | send_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, |
466 | const struct GNUNET_HashCode *key, | 295 | const struct GNUNET_HashCode *key, |
467 | const struct GNUNET_MESSENGER_Message *message) | 296 | const struct GNUNET_MESSENGER_Message *message) |
468 | { | 297 | { |
469 | GNUNET_assert((handle) && (key) && (message)); | 298 | GNUNET_assert ((handle) && (key) && (message)); |
470 | 299 | ||
471 | const struct GNUNET_ShortHashCode *id = get_srv_handle_member_id (handle, key); | 300 | const struct GNUNET_ShortHashCode *id = get_srv_handle_member_id (handle, |
301 | key); | ||
472 | 302 | ||
473 | if (!id) | 303 | if (! id) |
474 | { | 304 | { |
475 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "It is required to be a member of a room to send messages!\n"); | 305 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
306 | "It is required to be a member of a room to send messages!\n"); | ||
476 | return GNUNET_NO; | 307 | return GNUNET_NO; |
477 | } | 308 | } |
478 | 309 | ||
479 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (handle->service, key); | 310 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending message with member id: %s\n", |
311 | GNUNET_sh2s (id)); | ||
480 | 312 | ||
481 | if (!room) | 313 | if (0 != GNUNET_memcmp (id, &(message->header.sender_id))) |
482 | { | 314 | { |
483 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "The room (%s) is unknown!\n", GNUNET_h2s (key)); | 315 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
316 | "Member id does not match with handle!\n"); | ||
484 | return GNUNET_NO; | 317 | return GNUNET_NO; |
485 | } | 318 | } |
486 | 319 | ||
487 | struct GNUNET_MESSENGER_Message *msg = copy_message(message); | 320 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (handle->service, |
321 | key); | ||
488 | 322 | ||
489 | GNUNET_memcpy(&(msg->header.sender_id), id, sizeof(*id)); | 323 | if (! room) |
324 | { | ||
325 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "The room (%s) is unknown!\n", | ||
326 | GNUNET_h2s (key)); | ||
327 | return GNUNET_NO; | ||
328 | } | ||
490 | 329 | ||
330 | struct GNUNET_MESSENGER_Message *msg = copy_message (message); | ||
491 | return send_srv_room_message (room, handle, msg); | 331 | return send_srv_room_message (room, handle, msg); |
492 | } | 332 | } |
493 | 333 | ||
334 | |||
494 | static const struct GNUNET_HashCode* | 335 | static const struct GNUNET_HashCode* |
495 | get_next_member_session_contect(const struct GNUNET_MESSENGER_MemberSession *session) | 336 | get_next_member_session_context (const struct |
337 | GNUNET_MESSENGER_MemberSession *session) | ||
496 | { | 338 | { |
497 | if (session->next) | 339 | if (session->next) |
498 | return get_next_member_session_contect (session->next); | 340 | return get_next_member_session_context (session->next); |
499 | else | 341 | else |
500 | return get_member_session_context(session); | 342 | return get_member_session_context (session); |
501 | } | 343 | } |
502 | 344 | ||
345 | |||
503 | static const struct GNUNET_MESSENGER_MemberSession* | 346 | static const struct GNUNET_MESSENGER_MemberSession* |
504 | get_handle_member_session (struct GNUNET_MESSENGER_SrvHandle *handle, | 347 | get_handle_member_session (struct GNUNET_MESSENGER_SrvHandle *handle, |
505 | struct GNUNET_MESSENGER_SrvRoom *room, | 348 | struct GNUNET_MESSENGER_SrvRoom *room, |
506 | const struct GNUNET_HashCode *key) | 349 | const struct GNUNET_HashCode *key) |
507 | { | 350 | { |
508 | GNUNET_assert((handle) && (room) && (key) && (handle->service)); | 351 | GNUNET_assert ((handle) && (room) && (key) && (handle->service)); |
509 | 352 | ||
510 | const struct GNUNET_ShortHashCode *id = get_srv_handle_member_id(handle, key); | 353 | const struct GNUNET_ShortHashCode *id = get_srv_handle_member_id (handle, |
354 | key); | ||
511 | 355 | ||
512 | if (!id) | 356 | if (! id) |
357 | { | ||
358 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
359 | "Handle is missing a member id for its member session! (%s)\n", | ||
360 | GNUNET_h2s (key)); | ||
513 | return NULL; | 361 | return NULL; |
362 | } | ||
514 | 363 | ||
515 | struct GNUNET_MESSENGER_MemberStore *store = get_srv_room_member_store(room); | 364 | struct GNUNET_MESSENGER_MemberStore *store = get_srv_room_member_store (room); |
516 | struct GNUNET_MESSENGER_Member *member = get_store_member(store, id); | 365 | struct GNUNET_MESSENGER_Member *member = get_store_member (store, id); |
517 | 366 | ||
518 | const struct GNUNET_MESSENGER_Ego *ego = get_srv_handle_ego(handle); | 367 | const struct GNUNET_CRYPTO_PublicKey *pubkey = get_srv_handle_key (handle); |
519 | 368 | ||
520 | if (!ego) | 369 | if (! pubkey) |
370 | { | ||
371 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
372 | "Handle is missing a public key for its member session! (%s)\n", | ||
373 | GNUNET_h2s (key)); | ||
521 | return NULL; | 374 | return NULL; |
375 | } | ||
522 | 376 | ||
523 | return get_member_session(member, &(ego->pub)); | 377 | return get_member_session (member, pubkey); |
524 | } | 378 | } |
525 | 379 | ||
380 | |||
526 | void | 381 | void |
527 | notify_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, | 382 | notify_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, |
528 | struct GNUNET_MESSENGER_SrvRoom *room, | 383 | struct GNUNET_MESSENGER_SrvRoom *room, |
529 | const struct GNUNET_MESSENGER_MemberSession *session, | 384 | const struct GNUNET_MESSENGER_SenderSession *session, |
530 | const struct GNUNET_MESSENGER_Message *message, | 385 | const struct GNUNET_MESSENGER_Message *message, |
531 | const struct GNUNET_HashCode *hash) | 386 | const struct GNUNET_HashCode *hash, |
387 | enum GNUNET_GenericReturnValue recent) | ||
532 | { | 388 | { |
533 | GNUNET_assert((handle) && (room) && (session) && (message) && (hash)); | 389 | GNUNET_assert ((handle) && (room) && (session) && (message) && (hash)); |
534 | 390 | ||
535 | const struct GNUNET_HashCode *key = get_srv_room_key(room); | 391 | const struct GNUNET_HashCode *key = get_srv_room_key (room); |
536 | 392 | ||
537 | if ((!handle->mq) || (!get_srv_handle_member_id (handle, key))) | 393 | if ((! handle->mq) || (! get_srv_handle_member_id (handle, key))) |
538 | { | 394 | { |
539 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Notifying client about message requires membership!\n"); | 395 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
396 | "Notifying client about message requires membership!\n"); | ||
540 | return; | 397 | return; |
541 | } | 398 | } |
542 | 399 | ||
543 | const struct GNUNET_CRYPTO_PublicKey *pubkey = get_contact_key(session->contact); | ||
544 | |||
545 | struct GNUNET_HashCode sender; | 400 | struct GNUNET_HashCode sender; |
546 | GNUNET_CRYPTO_hash(pubkey, sizeof(*pubkey), &sender); | 401 | const struct GNUNET_HashCode *context = NULL; |
547 | |||
548 | const struct GNUNET_HashCode *context = get_next_member_session_contect (session); | ||
549 | 402 | ||
550 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Notifying client about message: %s\n", GNUNET_h2s (hash)); | 403 | if (GNUNET_YES == is_peer_message (message)) |
551 | 404 | { | |
552 | struct GNUNET_MESSENGER_Message *private_message = NULL; | 405 | const struct GNUNET_PeerIdentity *identity = session->peer; |
406 | GNUNET_CRYPTO_hash (identity, sizeof(*identity), &sender); | ||
553 | 407 | ||
554 | if (GNUNET_MESSENGER_KIND_PRIVATE == message->header.kind) | 408 | context = &sender; |
409 | } | ||
410 | else | ||
555 | { | 411 | { |
556 | private_message = copy_message(message); | 412 | const struct GNUNET_CRYPTO_PublicKey *pubkey = get_contact_key ( |
413 | session->member->contact); | ||
414 | GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &sender); | ||
557 | 415 | ||
558 | if (GNUNET_YES != decrypt_message(private_message, &(get_srv_handle_ego(handle)->priv))) | 416 | 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 | } | 417 | } |
566 | 418 | ||
419 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Notifying client about message: %s\n", | ||
420 | GNUNET_h2s (hash)); | ||
421 | |||
567 | struct GNUNET_MESSENGER_RecvMessage *msg; | 422 | struct GNUNET_MESSENGER_RecvMessage *msg; |
568 | struct GNUNET_MQ_Envelope *env; | 423 | struct GNUNET_MQ_Envelope *env; |
569 | 424 | ||
570 | uint16_t length = get_message_size (message, GNUNET_YES); | 425 | uint16_t length = get_message_size (message, GNUNET_YES); |
571 | 426 | ||
572 | env = GNUNET_MQ_msg_extra(msg, length, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE); | 427 | env = GNUNET_MQ_msg_extra (msg, length, |
428 | GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE); | ||
573 | 429 | ||
574 | GNUNET_memcpy(&(msg->key), key, sizeof(msg->key)); | 430 | GNUNET_memcpy (&(msg->key), key, sizeof(msg->key)); |
575 | GNUNET_memcpy(&(msg->sender), &sender, sizeof(msg->sender)); | 431 | GNUNET_memcpy (&(msg->sender), &sender, sizeof(msg->sender)); |
576 | GNUNET_memcpy(&(msg->context), context, sizeof(msg->context)); | 432 | GNUNET_memcpy (&(msg->context), context, sizeof(msg->context)); |
577 | GNUNET_memcpy(&(msg->hash), hash, sizeof(msg->hash)); | 433 | GNUNET_memcpy (&(msg->hash), hash, sizeof(msg->hash)); |
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) | 442 | if (GNUNET_YES == recent) |
585 | msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_PRIVATE; | 443 | msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_RECENT; |
586 | 444 | ||
587 | char *buffer = ((char*) msg) + sizeof(*msg); | 445 | char *buffer = ((char*) msg) + sizeof(*msg); |
588 | encode_message (message, length, buffer, GNUNET_YES); | 446 | encode_message (message, length, buffer, GNUNET_YES); |
589 | 447 | ||
590 | if (private_message) | ||
591 | destroy_message(private_message); | ||
592 | |||
593 | GNUNET_MQ_send (handle->mq, env); | 448 | GNUNET_MQ_send (handle->mq, env); |
594 | } | 449 | } |
595 | 450 | ||
451 | |||
596 | static int | 452 | static int |
597 | callback_scan_for_rooms (void *cls, | 453 | iterate_next_member_ids (void *cls, |
598 | const char *filename) | 454 | const struct GNUNET_HashCode *key, |
455 | void *value) | ||
599 | { | 456 | { |
600 | struct GNUNET_MESSENGER_SrvHandle *handle = cls; | 457 | struct GNUNET_MESSENGER_SrvHandle *handle = cls; |
458 | struct GNUNET_MESSENGER_NextMemberId *next = value; | ||
601 | 459 | ||
602 | if ((strlen(filename) <= 4) || (0 != strcmp(filename + strlen(filename) - 4, ".cfg"))) | 460 | struct GNUNET_MESSENGER_MemberMessage *msg; |
603 | return GNUNET_OK; | 461 | struct GNUNET_MQ_Envelope *env; |
604 | |||
605 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Load room configuration of handle: %s\n", filename); | ||
606 | 462 | ||
607 | struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); | 463 | env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID); |
608 | 464 | ||
609 | if ((GNUNET_YES == GNUNET_DISK_file_test (filename)) && (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, filename))) | 465 | GNUNET_memcpy (&(msg->key), key, sizeof(*key)); |
610 | { | 466 | GNUNET_memcpy (&(msg->id), &(next->id), sizeof(next->id)); |
611 | struct GNUNET_HashCode key; | 467 | msg->reset = (uint32_t) next->reset; |
612 | struct GNUNET_ShortHashCode member_id; | ||
613 | 468 | ||
614 | if ((GNUNET_OK == GNUNET_CONFIGURATION_get_data (cfg, "room", "key", &key, sizeof(key))) && | 469 | 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 | 470 | ||
619 | GNUNET_CONFIGURATION_destroy (cfg); | 471 | GNUNET_free (next); |
620 | return GNUNET_OK; | 472 | return GNUNET_YES; |
621 | } | 473 | } |
622 | 474 | ||
623 | void | ||
624 | load_srv_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle) | ||
625 | { | ||
626 | GNUNET_assert(handle); | ||
627 | |||
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 | 475 | ||
636 | if (GNUNET_OK == GNUNET_DISK_directory_test (scan_dir, GNUNET_YES)) | 476 | static void |
637 | GNUNET_DISK_directory_scan (scan_dir, callback_scan_for_rooms, handle); | 477 | task_notify_srv_handle_member_id (void *cls) |
638 | |||
639 | GNUNET_free(scan_dir); | ||
640 | } | ||
641 | |||
642 | GNUNET_free(id_dir); | ||
643 | } | ||
644 | |||
645 | static int | ||
646 | iterate_save_rooms (void *cls, | ||
647 | const struct GNUNET_HashCode *key, | ||
648 | void *value) | ||
649 | { | 478 | { |
650 | struct GNUNET_MESSENGER_SrvHandle *handle = cls; | 479 | struct GNUNET_MESSENGER_SrvHandle *handle = cls; |
651 | struct GNUNET_ShortHashCode *member_id = value; | 480 | handle->notify = NULL; |
652 | |||
653 | char *id_dir; | ||
654 | get_srv_handle_data_subdir (handle, handle->name, &id_dir); | ||
655 | 481 | ||
656 | char *filename; | 482 | GNUNET_CONTAINER_multihashmap_iterate (handle->next_ids, |
657 | GNUNET_asprintf (&filename, "%s%s%c%s.cfg", id_dir, "rooms", DIR_SEPARATOR, GNUNET_h2s (key)); | 483 | iterate_next_member_ids, handle); |
658 | GNUNET_free(id_dir); | 484 | GNUNET_CONTAINER_multihashmap_clear (handle->next_ids); |
659 | 485 | } | |
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 | |||
666 | if (key_data) | ||
667 | { | ||
668 | GNUNET_CONFIGURATION_set_value_string (cfg, "room", "key", key_data); | ||
669 | 486 | ||
670 | GNUNET_free(key_data); | ||
671 | } | ||
672 | 487 | ||
673 | char *member_id_data = GNUNET_STRINGS_data_to_string_alloc (member_id, sizeof(*member_id)); | 488 | void |
489 | notify_srv_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
490 | struct GNUNET_MESSENGER_SrvRoom *room, | ||
491 | const struct GNUNET_ShortHashCode *member_id, | ||
492 | enum GNUNET_GenericReturnValue reset) | ||
493 | { | ||
494 | GNUNET_assert ((handle) && (room) && (member_id)); | ||
674 | 495 | ||
675 | if (member_id_data) | 496 | struct GNUNET_MESSENGER_NextMemberId *next = GNUNET_new (struct |
497 | GNUNET_MESSENGER_NextMemberId); | ||
498 | if (! next) | ||
676 | { | 499 | { |
677 | GNUNET_CONFIGURATION_set_value_string (cfg, "room", "member_id", member_id_data); | 500 | return; |
678 | |||
679 | GNUNET_free(member_id_data); | ||
680 | } | 501 | } |
681 | 502 | ||
682 | GNUNET_CONFIGURATION_write (cfg, filename); | 503 | GNUNET_memcpy (&(next->id), member_id, sizeof(next->id)); |
683 | GNUNET_CONFIGURATION_destroy (cfg); | 504 | next->reset = reset; |
684 | 505 | ||
685 | GNUNET_free(filename); | 506 | const struct GNUNET_HashCode *key = get_srv_room_key (room); |
686 | 507 | ||
687 | return GNUNET_YES; | 508 | struct GNUNET_MESSENGER_NextMemberId *prev = |
688 | } | 509 | GNUNET_CONTAINER_multihashmap_get (handle->next_ids, key); |
689 | 510 | if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_put (handle->next_ids, key, | |
690 | void | 511 | next, |
691 | save_srv_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle) | 512 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)) |
692 | { | ||
693 | GNUNET_assert(handle); | ||
694 | |||
695 | char *id_dir; | ||
696 | get_srv_handle_data_subdir (handle, handle->name, &id_dir); | ||
697 | |||
698 | if ((GNUNET_YES == GNUNET_DISK_directory_test (id_dir, GNUNET_NO)) || (GNUNET_OK | ||
699 | == GNUNET_DISK_directory_create (id_dir))) | ||
700 | { | 513 | { |
701 | char *save_dir; | 514 | 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 | } | 515 | } |
710 | 516 | ||
711 | GNUNET_free(id_dir); | 517 | if (prev) |
518 | GNUNET_free (prev); | ||
519 | |||
520 | if (! handle->notify) | ||
521 | handle->notify = GNUNET_SCHEDULER_add_now (task_notify_srv_handle_member_id, | ||
522 | handle); | ||
712 | } | 523 | } |