diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-06-21 22:27:17 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-06-21 22:27:17 +0000 |
commit | dd9ed7931e52705b216c346127108520c5e4460b (patch) | |
tree | 3091fc4c7d2eaa93c5cd746e3d7ac155c2ff815e /src/identity/identity_api.c | |
parent | 028d6d5d44aa4affbc5e78d5bb26a9254fe7a13b (diff) | |
download | gnunet-dd9ed7931e52705b216c346127108520c5e4460b.tar.gz gnunet-dd9ed7931e52705b216c346127108520c5e4460b.zip |
rework identity API to use new MQ API
Diffstat (limited to 'src/identity/identity_api.c')
-rw-r--r-- | src/identity/identity_api.c | 872 |
1 files changed, 421 insertions, 451 deletions
diff --git a/src/identity/identity_api.c b/src/identity/identity_api.c index 1406ddd41..3c8dc49b1 100644 --- a/src/identity/identity_api.c +++ b/src/identity/identity_api.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2013 GNUnet e.V. | 3 | Copyright (C) 2013, 2016 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public Liceidentity as published | 6 | it under the terms of the GNU General Public Liceidentity as published |
@@ -117,13 +117,13 @@ struct GNUNET_IDENTITY_Handle | |||
117 | const struct GNUNET_CONFIGURATION_Handle *cfg; | 117 | const struct GNUNET_CONFIGURATION_Handle *cfg; |
118 | 118 | ||
119 | /** | 119 | /** |
120 | * Socket (if available). | 120 | * Connection to service. |
121 | */ | 121 | */ |
122 | struct GNUNET_CLIENT_Connection *client; | 122 | struct GNUNET_MQ_Handle *mq; |
123 | 123 | ||
124 | /** | 124 | /** |
125 | * Hash map from the hash of the public key to the | 125 | * Hash map from the hash of the public key to the |
126 | * respective 'GNUNET_IDENTITY_Ego' handle. | 126 | * respective `GNUNET_IDENTITY_Ego` handle. |
127 | */ | 127 | */ |
128 | struct GNUNET_CONTAINER_MultiHashMap *egos; | 128 | struct GNUNET_CONTAINER_MultiHashMap *egos; |
129 | 129 | ||
@@ -133,7 +133,7 @@ struct GNUNET_IDENTITY_Handle | |||
133 | GNUNET_IDENTITY_Callback cb; | 133 | GNUNET_IDENTITY_Callback cb; |
134 | 134 | ||
135 | /** | 135 | /** |
136 | * Closure for 'cb'. | 136 | * Closure for @e cb. |
137 | */ | 137 | */ |
138 | void *cb_cls; | 138 | void *cb_cls; |
139 | 139 | ||
@@ -148,14 +148,9 @@ struct GNUNET_IDENTITY_Handle | |||
148 | struct GNUNET_IDENTITY_Operation *op_tail; | 148 | struct GNUNET_IDENTITY_Operation *op_tail; |
149 | 149 | ||
150 | /** | 150 | /** |
151 | * Currently pending transmission request, or NULL for none. | ||
152 | */ | ||
153 | struct GNUNET_CLIENT_TransmitHandle *th; | ||
154 | |||
155 | /** | ||
156 | * Task doing exponential back-off trying to reconnect. | 151 | * Task doing exponential back-off trying to reconnect. |
157 | */ | 152 | */ |
158 | struct GNUNET_SCHEDULER_Task * reconnect_task; | 153 | struct GNUNET_SCHEDULER_Task *reconnect_task; |
159 | 154 | ||
160 | /** | 155 | /** |
161 | * Time for next connect retry. | 156 | * Time for next connect retry. |
@@ -185,8 +180,10 @@ GNUNET_IDENTITY_ego_get_anonymous () | |||
185 | return &anon; | 180 | return &anon; |
186 | anon.pk = (struct GNUNET_CRYPTO_EcdsaPrivateKey *) GNUNET_CRYPTO_ecdsa_key_get_anonymous (); | 181 | anon.pk = (struct GNUNET_CRYPTO_EcdsaPrivateKey *) GNUNET_CRYPTO_ecdsa_key_get_anonymous (); |
187 | GNUNET_CRYPTO_ecdsa_key_get_public (anon.pk, | 182 | GNUNET_CRYPTO_ecdsa_key_get_public (anon.pk, |
188 | &pub); | 183 | &pub); |
189 | GNUNET_CRYPTO_hash (&pub, sizeof (pub), &anon.id); | 184 | GNUNET_CRYPTO_hash (&pub, |
185 | sizeof (pub), | ||
186 | &anon.id); | ||
190 | return &anon; | 187 | return &anon; |
191 | } | 188 | } |
192 | 189 | ||
@@ -201,6 +198,38 @@ reconnect (void *cls); | |||
201 | 198 | ||
202 | 199 | ||
203 | /** | 200 | /** |
201 | * Free ego from hash map. | ||
202 | * | ||
203 | * @param cls identity service handle | ||
204 | * @param key unused | ||
205 | * @param value ego to free | ||
206 | * @return #GNUNET_OK (continue to iterate) | ||
207 | */ | ||
208 | static int | ||
209 | free_ego (void *cls, | ||
210 | const struct GNUNET_HashCode *key, | ||
211 | void *value) | ||
212 | { | ||
213 | struct GNUNET_IDENTITY_Handle *h = cls; | ||
214 | struct GNUNET_IDENTITY_Ego *ego = value; | ||
215 | |||
216 | if (NULL != h->cb) | ||
217 | h->cb (h->cb_cls, | ||
218 | ego, | ||
219 | &ego->ctx, | ||
220 | NULL); | ||
221 | GNUNET_free (ego->pk); | ||
222 | GNUNET_free (ego->name); | ||
223 | GNUNET_assert (GNUNET_YES == | ||
224 | GNUNET_CONTAINER_multihashmap_remove (h->egos, | ||
225 | key, | ||
226 | value)); | ||
227 | GNUNET_free (ego); | ||
228 | return GNUNET_OK; | ||
229 | } | ||
230 | |||
231 | |||
232 | /** | ||
204 | * Reschedule a connect attempt to the service. | 233 | * Reschedule a connect attempt to the service. |
205 | * | 234 | * |
206 | * @param h transport service to reconnect | 235 | * @param h transport service to reconnect |
@@ -208,322 +237,310 @@ reconnect (void *cls); | |||
208 | static void | 237 | static void |
209 | reschedule_connect (struct GNUNET_IDENTITY_Handle *h) | 238 | reschedule_connect (struct GNUNET_IDENTITY_Handle *h) |
210 | { | 239 | { |
211 | GNUNET_assert (h->reconnect_task == NULL); | 240 | struct GNUNET_IDENTITY_Operation *op; |
212 | 241 | ||
213 | if (NULL != h->th) | 242 | GNUNET_assert (NULL == h->reconnect_task); |
243 | |||
244 | if (NULL != h->mq) | ||
214 | { | 245 | { |
215 | GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); | 246 | GNUNET_MQ_destroy (h->mq); |
216 | h->th = NULL; | 247 | h->mq = NULL; |
217 | } | 248 | } |
218 | if (NULL != h->client) | 249 | while (NULL != (op = h->op_head)) |
219 | { | 250 | { |
220 | GNUNET_CLIENT_disconnect (h->client); | 251 | GNUNET_CONTAINER_DLL_remove (h->op_head, |
221 | h->client = NULL; | 252 | h->op_tail, |
253 | op); | ||
254 | if (NULL != op->cont) | ||
255 | op->cont (op->cls, | ||
256 | "Error in communication with the identity service"); | ||
257 | else if (NULL != op->cb) | ||
258 | op->cb (op->cls, | ||
259 | NULL, | ||
260 | NULL, | ||
261 | NULL); | ||
262 | GNUNET_free (op); | ||
222 | } | 263 | } |
223 | h->in_receive = GNUNET_NO; | 264 | GNUNET_CONTAINER_multihashmap_iterate (h->egos, |
265 | &free_ego, | ||
266 | h); | ||
224 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 267 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
225 | "Scheduling task to reconnect to identity service in %s.\n", | 268 | "Scheduling task to reconnect to identity service in %s.\n", |
226 | GNUNET_STRINGS_relative_time_to_string (h->reconnect_delay, GNUNET_YES)); | 269 | GNUNET_STRINGS_relative_time_to_string (h->reconnect_delay, |
270 | GNUNET_YES)); | ||
227 | h->reconnect_task = | 271 | h->reconnect_task = |
228 | GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h); | 272 | GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, |
273 | &reconnect, | ||
274 | h); | ||
229 | h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay); | 275 | h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay); |
230 | } | 276 | } |
231 | 277 | ||
232 | 278 | ||
233 | /** | 279 | /** |
234 | * Type of a function to call when we receive a message | 280 | * Generic error handler, called with the appropriate error code and |
235 | * from the service. | 281 | * the same closure specified at the creation of the message queue. |
282 | * Not every message queue implementation supports an error handler. | ||
236 | * | 283 | * |
237 | * @param cls closure | 284 | * @param cls closure with the `struct GNUNET_IDENTITY_Handle *` |
238 | * @param msg message received, NULL on timeout or fatal error | 285 | * @param error error code |
239 | */ | 286 | */ |
240 | static void | 287 | static void |
241 | message_handler (void *cls, | 288 | mq_error_handler (void *cls, |
242 | const struct GNUNET_MessageHeader *msg) | 289 | enum GNUNET_MQ_Error error) |
243 | { | 290 | { |
244 | struct GNUNET_IDENTITY_Handle *h = cls; | 291 | struct GNUNET_IDENTITY_Handle *h = cls; |
245 | struct GNUNET_IDENTITY_Operation *op; | ||
246 | struct GNUNET_IDENTITY_Ego *ego; | ||
247 | const struct GNUNET_IDENTITY_ResultCodeMessage *rcm; | ||
248 | const struct GNUNET_IDENTITY_UpdateMessage *um; | ||
249 | const struct GNUNET_IDENTITY_SetDefaultMessage *sdm; | ||
250 | struct GNUNET_CRYPTO_EcdsaPublicKey pub; | ||
251 | struct GNUNET_HashCode id; | ||
252 | const char *str; | ||
253 | uint16_t size; | ||
254 | uint16_t name_len; | ||
255 | 292 | ||
256 | if (NULL == msg) | 293 | reschedule_connect (h); |
294 | } | ||
295 | |||
296 | |||
297 | /** | ||
298 | * We received a result code from the service. Check the message | ||
299 | * is well-formed. | ||
300 | * | ||
301 | * @param cls closure | ||
302 | * @param rcm result message received | ||
303 | * @return #GNUNET_OK if the message is well-formed | ||
304 | */ | ||
305 | static int | ||
306 | check_identity_result_code (void *cls, | ||
307 | const struct GNUNET_IDENTITY_ResultCodeMessage *rcm) | ||
308 | { | ||
309 | uint16_t size = ntohs (rcm->header.size) - sizeof (*rcm); | ||
310 | const char *str = (const char *) &rcm[1]; | ||
311 | |||
312 | if (0 == size) | ||
313 | return GNUNET_OK; | ||
314 | if ('\0' != str[size - sizeof (*rcm) - 1]) | ||
257 | { | 315 | { |
258 | reschedule_connect (h); | 316 | GNUNET_break (0); |
259 | return; | 317 | return GNUNET_SYSERR; |
260 | } | 318 | } |
261 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 319 | return GNUNET_OK; |
262 | "Received message of type %d from identity service\n", | 320 | } |
263 | ntohs (msg->type)); | ||
264 | size = ntohs (msg->size); | ||
265 | switch (ntohs (msg->type)) | ||
266 | { | ||
267 | case GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE: | ||
268 | if (size < sizeof (struct GNUNET_IDENTITY_ResultCodeMessage)) | ||
269 | { | ||
270 | GNUNET_break (0); | ||
271 | reschedule_connect (h); | ||
272 | return; | ||
273 | } | ||
274 | rcm = (const struct GNUNET_IDENTITY_ResultCodeMessage *) msg; | ||
275 | str = (const char *) &rcm[1]; | ||
276 | if ( (size > sizeof (struct GNUNET_IDENTITY_ResultCodeMessage)) && | ||
277 | ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_ResultCodeMessage) - 1]) ) | ||
278 | { | ||
279 | GNUNET_break (0); | ||
280 | reschedule_connect (h); | ||
281 | return; | ||
282 | } | ||
283 | if (size == sizeof (struct GNUNET_IDENTITY_ResultCodeMessage)) | ||
284 | str = NULL; | ||
285 | 321 | ||
286 | op = h->op_head; | ||
287 | GNUNET_CONTAINER_DLL_remove (h->op_head, | ||
288 | h->op_tail, | ||
289 | op); | ||
290 | GNUNET_CLIENT_receive (h->client, &message_handler, h, | ||
291 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
292 | if (NULL != op->cont) | ||
293 | op->cont (op->cls, | ||
294 | str); | ||
295 | else if (NULL != op->cb) | ||
296 | op->cb (op->cls, NULL, NULL, NULL); | ||
297 | GNUNET_free (op); | ||
298 | break; | ||
299 | case GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE: | ||
300 | if (size < sizeof (struct GNUNET_IDENTITY_UpdateMessage)) | ||
301 | { | ||
302 | GNUNET_break (0); | ||
303 | reschedule_connect (h); | ||
304 | return; | ||
305 | } | ||
306 | um = (const struct GNUNET_IDENTITY_UpdateMessage *) msg; | ||
307 | name_len = ntohs (um->name_len); | ||
308 | 322 | ||
309 | str = (const char *) &um[1]; | 323 | /** |
310 | if ( (size != name_len + sizeof (struct GNUNET_IDENTITY_UpdateMessage)) || | 324 | * We received a result code from the service. |
311 | ( (0 != name_len) && | 325 | * |
312 | ('\0' != str[name_len - 1])) ) | 326 | * @param cls closure |
313 | { | 327 | * @param rcm result message received |
314 | GNUNET_break (0); | 328 | */ |
315 | reschedule_connect (h); | 329 | static void |
316 | return; | 330 | handle_identity_result_code (void *cls, |
317 | } | 331 | const struct GNUNET_IDENTITY_ResultCodeMessage *rcm) |
318 | if (GNUNET_YES == ntohs (um->end_of_list)) | 332 | { |
319 | { | 333 | struct GNUNET_IDENTITY_Handle *h = cls; |
320 | /* end of initial list of data */ | 334 | struct GNUNET_IDENTITY_Operation *op; |
321 | GNUNET_CLIENT_receive (h->client, &message_handler, h, | 335 | uint16_t size = ntohs (rcm->header.size) - sizeof (*rcm); |
322 | GNUNET_TIME_UNIT_FOREVER_REL); | 336 | const char *str = (0 == size) ? NULL : (const char *) &rcm[1]; |
323 | if (NULL != h->cb) | 337 | |
324 | h->cb (h->cb_cls, NULL, NULL, NULL); | 338 | op = h->op_head; |
325 | break; | 339 | if (NULL == op) |
326 | } | 340 | { |
327 | GNUNET_CRYPTO_ecdsa_key_get_public (&um->private_key, | ||
328 | &pub); | ||
329 | GNUNET_CRYPTO_hash (&pub, sizeof (pub), &id); | ||
330 | if (0 == name_len) | ||
331 | str = NULL; | ||
332 | else | ||
333 | str = (const char *) &um[1]; | ||
334 | ego = GNUNET_CONTAINER_multihashmap_get (h->egos, | ||
335 | &id); | ||
336 | if (NULL == ego) | ||
337 | { | ||
338 | /* ego was created */ | ||
339 | if (NULL == str) | ||
340 | { | ||
341 | /* deletion of unknown ego? not allowed */ | ||
342 | GNUNET_break (0); | ||
343 | reschedule_connect (h); | ||
344 | return; | ||
345 | } | ||
346 | ego = GNUNET_new (struct GNUNET_IDENTITY_Ego); | ||
347 | ego->pk = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey); | ||
348 | *ego->pk = um->private_key; | ||
349 | ego->name = GNUNET_strdup (str); | ||
350 | ego->id = id; | ||
351 | GNUNET_assert (GNUNET_YES == | ||
352 | GNUNET_CONTAINER_multihashmap_put (h->egos, | ||
353 | &ego->id, | ||
354 | ego, | ||
355 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
356 | } | ||
357 | if (NULL == str) | ||
358 | { | ||
359 | /* ego was deleted */ | ||
360 | GNUNET_assert (GNUNET_YES == | ||
361 | GNUNET_CONTAINER_multihashmap_remove (h->egos, | ||
362 | &ego->id, | ||
363 | ego)); | ||
364 | } | ||
365 | else | ||
366 | { | ||
367 | /* ego changed name */ | ||
368 | GNUNET_free (ego->name); | ||
369 | ego->name = GNUNET_strdup (str); | ||
370 | } | ||
371 | GNUNET_CLIENT_receive (h->client, &message_handler, h, | ||
372 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
373 | /* inform application about change */ | ||
374 | if (NULL != h->cb) | ||
375 | h->cb (h->cb_cls, | ||
376 | ego, | ||
377 | &ego->ctx, | ||
378 | str); | ||
379 | if (NULL == str) | ||
380 | { | ||
381 | GNUNET_free (ego->pk); | ||
382 | GNUNET_free (ego->name); | ||
383 | GNUNET_free (ego); | ||
384 | } | ||
385 | break; | ||
386 | case GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT: | ||
387 | if (size < sizeof (struct GNUNET_IDENTITY_SetDefaultMessage)) | ||
388 | { | ||
389 | GNUNET_break (0); | ||
390 | reschedule_connect (h); | ||
391 | return; | ||
392 | } | ||
393 | sdm = (const struct GNUNET_IDENTITY_SetDefaultMessage *) msg; | ||
394 | GNUNET_break (0 == ntohs (sdm->reserved)); | ||
395 | name_len = ntohs (sdm->name_len); | ||
396 | str = (const char *) &sdm[1]; | ||
397 | if ( (size != name_len + sizeof (struct GNUNET_IDENTITY_SetDefaultMessage)) || | ||
398 | ( (0 != name_len) && | ||
399 | ('\0' != str[name_len - 1]) ) ) | ||
400 | { | ||
401 | GNUNET_break (0); | ||
402 | reschedule_connect (h); | ||
403 | return; | ||
404 | } | ||
405 | /* Note: we know which service this should be for, so we're not | ||
406 | really using 'str' henceforth */ | ||
407 | GNUNET_CRYPTO_ecdsa_key_get_public (&sdm->private_key, | ||
408 | &pub); | ||
409 | GNUNET_CRYPTO_hash (&pub, sizeof (pub), &id); | ||
410 | ego = GNUNET_CONTAINER_multihashmap_get (h->egos, | ||
411 | &id); | ||
412 | if (NULL == ego) | ||
413 | { | ||
414 | GNUNET_break (0); | ||
415 | reschedule_connect (h); | ||
416 | return; | ||
417 | } | ||
418 | op = h->op_head; | ||
419 | if (NULL == op) | ||
420 | { | ||
421 | GNUNET_break (0); | ||
422 | reschedule_connect (h); | ||
423 | return; | ||
424 | } | ||
425 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
426 | "Received SET_DEFAULT message from identity service\n"); | ||
427 | GNUNET_CONTAINER_DLL_remove (h->op_head, | ||
428 | h->op_tail, | ||
429 | op); | ||
430 | GNUNET_CLIENT_receive (h->client, &message_handler, h, | ||
431 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
432 | if (NULL != op->cb) | ||
433 | op->cb (op->cls, | ||
434 | ego, | ||
435 | &ego->ctx, | ||
436 | ego->name); | ||
437 | GNUNET_free (op); | ||
438 | break; | ||
439 | default: | ||
440 | GNUNET_break (0); | 341 | GNUNET_break (0); |
441 | reschedule_connect (h); | 342 | reschedule_connect (h); |
442 | return; | 343 | return; |
443 | } | 344 | } |
345 | GNUNET_CONTAINER_DLL_remove (h->op_head, | ||
346 | h->op_tail, | ||
347 | op); | ||
348 | if (NULL != op->cont) | ||
349 | op->cont (op->cls, | ||
350 | str); | ||
351 | else if (NULL != op->cb) | ||
352 | op->cb (op->cls, NULL, NULL, NULL); | ||
353 | GNUNET_free (op); | ||
444 | } | 354 | } |
445 | 355 | ||
446 | 356 | ||
447 | /** | 357 | /** |
448 | * Schedule transmission of the next message from our queue. | 358 | * Check validity of identity update message. |
449 | * | 359 | * |
450 | * @param h identity handle | 360 | * @param cls closure |
361 | * @param um message received | ||
362 | * @return #GNUNET_OK if the message is well-formed | ||
451 | */ | 363 | */ |
452 | static void | 364 | static int |
453 | transmit_next (struct GNUNET_IDENTITY_Handle *h); | 365 | check_identity_update (void *cls, |
366 | const struct GNUNET_IDENTITY_UpdateMessage *um) | ||
367 | { | ||
368 | uint16_t size = ntohs (um->header.size); | ||
369 | uint16_t name_len = ntohs (um->name_len); | ||
370 | const char *str = (const char *) &um[1]; | ||
371 | |||
372 | if ( (size != name_len + sizeof (struct GNUNET_IDENTITY_UpdateMessage)) || | ||
373 | ( (0 != name_len) && | ||
374 | ('\0' != str[name_len - 1])) ) | ||
375 | { | ||
376 | GNUNET_break (0); | ||
377 | return GNUNET_SYSERR; | ||
378 | } | ||
379 | return GNUNET_OK; | ||
380 | } | ||
454 | 381 | ||
455 | 382 | ||
456 | /** | 383 | /** |
457 | * Transmit next message to service. | 384 | * Handle identity update message. |
458 | * | 385 | * |
459 | * @param cls the `struct GNUNET_IDENTITY_Handle`. | 386 | * @param cls closure |
460 | * @param size number of bytes available in @a buf | 387 | * @param um message received |
461 | * @param buf where to copy the message | ||
462 | * @return number of bytes copied to buf | ||
463 | */ | 388 | */ |
464 | static size_t | 389 | static void |
465 | send_next_message (void *cls, | 390 | handle_identity_update (void *cls, |
466 | size_t size, | 391 | const struct GNUNET_IDENTITY_UpdateMessage *um) |
467 | void *buf) | ||
468 | { | 392 | { |
469 | struct GNUNET_IDENTITY_Handle *h = cls; | 393 | struct GNUNET_IDENTITY_Handle *h = cls; |
470 | struct GNUNET_IDENTITY_Operation *op = h->op_head; | 394 | uint16_t name_len = ntohs (um->name_len); |
471 | size_t ret; | 395 | const char *str = (0 == name_len) ? NULL : (const char *) &um[1]; |
396 | struct GNUNET_CRYPTO_EcdsaPublicKey pub; | ||
397 | struct GNUNET_HashCode id; | ||
398 | struct GNUNET_IDENTITY_Ego *ego; | ||
472 | 399 | ||
473 | h->th = NULL; | 400 | if (GNUNET_YES == ntohs (um->end_of_list)) |
474 | if (NULL == op) | ||
475 | return 0; | ||
476 | ret = ntohs (op->msg->size); | ||
477 | if (ret > size) | ||
478 | { | 401 | { |
479 | reschedule_connect (h); | 402 | /* end of initial list of data */ |
480 | return 0; | 403 | if (NULL != h->cb) |
404 | h->cb (h->cb_cls, | ||
405 | NULL, | ||
406 | NULL, | ||
407 | NULL); | ||
408 | return; | ||
481 | } | 409 | } |
482 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 410 | GNUNET_CRYPTO_ecdsa_key_get_public (&um->private_key, |
483 | "Sending message of type %d to identity service\n", | 411 | &pub); |
484 | ntohs (op->msg->type)); | 412 | GNUNET_CRYPTO_hash (&pub, |
485 | memcpy (buf, op->msg, ret); | 413 | sizeof (pub), |
486 | if ( (NULL == op->cont) && | 414 | &id); |
487 | (NULL == op->cb) ) | 415 | ego = GNUNET_CONTAINER_multihashmap_get (h->egos, |
416 | &id); | ||
417 | if (NULL == ego) | ||
488 | { | 418 | { |
489 | GNUNET_CONTAINER_DLL_remove (h->op_head, | 419 | /* ego was created */ |
490 | h->op_tail, | 420 | if (NULL == str) |
491 | op); | 421 | { |
492 | GNUNET_free (op); | 422 | /* deletion of unknown ego? not allowed */ |
493 | transmit_next (h); | 423 | GNUNET_break (0); |
424 | reschedule_connect (h); | ||
425 | return; | ||
426 | } | ||
427 | ego = GNUNET_new (struct GNUNET_IDENTITY_Ego); | ||
428 | ego->pk = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey); | ||
429 | *ego->pk = um->private_key; | ||
430 | ego->name = GNUNET_strdup (str); | ||
431 | ego->id = id; | ||
432 | GNUNET_assert (GNUNET_YES == | ||
433 | GNUNET_CONTAINER_multihashmap_put (h->egos, | ||
434 | &ego->id, | ||
435 | ego, | ||
436 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
437 | } | ||
438 | if (NULL == str) | ||
439 | { | ||
440 | /* ego was deleted */ | ||
441 | GNUNET_assert (GNUNET_YES == | ||
442 | GNUNET_CONTAINER_multihashmap_remove (h->egos, | ||
443 | &ego->id, | ||
444 | ego)); | ||
445 | } | ||
446 | else | ||
447 | { | ||
448 | /* ego changed name */ | ||
449 | GNUNET_free (ego->name); | ||
450 | ego->name = GNUNET_strdup (str); | ||
451 | } | ||
452 | /* inform application about change */ | ||
453 | if (NULL != h->cb) | ||
454 | h->cb (h->cb_cls, | ||
455 | ego, | ||
456 | &ego->ctx, | ||
457 | str); | ||
458 | /* complete deletion */ | ||
459 | if (NULL == str) | ||
460 | { | ||
461 | GNUNET_free (ego->pk); | ||
462 | GNUNET_free (ego->name); | ||
463 | GNUNET_free (ego); | ||
494 | } | 464 | } |
495 | if (GNUNET_NO == h->in_receive) | 465 | } |
466 | |||
467 | |||
468 | /** | ||
469 | * Function called when we receive a set default message from the | ||
470 | * service. | ||
471 | * | ||
472 | * @param cls closure | ||
473 | * @param sdm message received | ||
474 | * @return #GNUNET_OK if the message is well-formed | ||
475 | */ | ||
476 | static int | ||
477 | check_identity_set_default (void *cls, | ||
478 | const struct GNUNET_IDENTITY_SetDefaultMessage *sdm) | ||
479 | { | ||
480 | uint16_t size = ntohs (sdm->header.size); | ||
481 | uint16_t name_len = ntohs (sdm->name_len); | ||
482 | const char *str = (const char *) &sdm[1]; | ||
483 | |||
484 | if ( (size != name_len + sizeof (struct GNUNET_IDENTITY_SetDefaultMessage)) || | ||
485 | ( (0 != name_len) && | ||
486 | ('\0' != str[name_len - 1]) ) ) | ||
496 | { | 487 | { |
497 | h->in_receive = GNUNET_YES; | 488 | GNUNET_break (0); |
498 | GNUNET_CLIENT_receive (h->client, | 489 | return GNUNET_SYSERR; |
499 | &message_handler, h, | ||
500 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
501 | } | 490 | } |
502 | return ret; | 491 | GNUNET_break (0 == ntohs (sdm->reserved)); |
492 | return GNUNET_OK; | ||
503 | } | 493 | } |
504 | 494 | ||
505 | 495 | ||
506 | /** | 496 | /** |
507 | * Schedule transmission of the next message from our queue. | 497 | * Type of a function to call when we receive a message |
498 | * from the service. | ||
508 | * | 499 | * |
509 | * @param h identity handle | 500 | * @param cls closure |
501 | * @param sdm message received | ||
510 | */ | 502 | */ |
511 | static void | 503 | static void |
512 | transmit_next (struct GNUNET_IDENTITY_Handle *h) | 504 | handle_identity_set_default (void *cls, |
505 | const struct GNUNET_IDENTITY_SetDefaultMessage *sdm) | ||
513 | { | 506 | { |
514 | struct GNUNET_IDENTITY_Operation *op = h->op_head; | 507 | struct GNUNET_IDENTITY_Handle *h = cls; |
508 | struct GNUNET_IDENTITY_Operation *op; | ||
509 | struct GNUNET_CRYPTO_EcdsaPublicKey pub; | ||
510 | struct GNUNET_HashCode id; | ||
511 | struct GNUNET_IDENTITY_Ego *ego; | ||
515 | 512 | ||
516 | GNUNET_assert (NULL == h->th); | 513 | GNUNET_CRYPTO_ecdsa_key_get_public (&sdm->private_key, |
517 | if (NULL == op) | 514 | &pub); |
515 | GNUNET_CRYPTO_hash (&pub, | ||
516 | sizeof (pub), | ||
517 | &id); | ||
518 | ego = GNUNET_CONTAINER_multihashmap_get (h->egos, | ||
519 | &id); | ||
520 | if (NULL == ego) | ||
521 | { | ||
522 | GNUNET_break (0); | ||
523 | reschedule_connect (h); | ||
518 | return; | 524 | return; |
519 | if (NULL == h->client) | 525 | } |
526 | op = h->op_head; | ||
527 | if (NULL == op) | ||
528 | { | ||
529 | GNUNET_break (0); | ||
530 | reschedule_connect (h); | ||
520 | return; | 531 | return; |
521 | h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, | 532 | } |
522 | ntohs (op->msg->size), | 533 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
523 | GNUNET_TIME_UNIT_FOREVER_REL, | 534 | "Received SET_DEFAULT message from identity service\n"); |
524 | GNUNET_NO, | 535 | GNUNET_CONTAINER_DLL_remove (h->op_head, |
525 | &send_next_message, | 536 | h->op_tail, |
526 | h); | 537 | op); |
538 | if (NULL != op->cb) | ||
539 | op->cb (op->cls, | ||
540 | ego, | ||
541 | &ego->ctx, | ||
542 | ego->name); | ||
543 | GNUNET_free (op); | ||
527 | } | 544 | } |
528 | 545 | ||
529 | 546 | ||
@@ -535,32 +552,40 @@ transmit_next (struct GNUNET_IDENTITY_Handle *h) | |||
535 | static void | 552 | static void |
536 | reconnect (void *cls) | 553 | reconnect (void *cls) |
537 | { | 554 | { |
555 | GNUNET_MQ_hd_var_size (identity_result_code, | ||
556 | GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE, | ||
557 | struct GNUNET_IDENTITY_ResultCodeMessage); | ||
558 | GNUNET_MQ_hd_var_size (identity_update, | ||
559 | GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE, | ||
560 | struct GNUNET_IDENTITY_UpdateMessage); | ||
561 | GNUNET_MQ_hd_var_size (identity_set_default, | ||
562 | GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT, | ||
563 | struct GNUNET_IDENTITY_SetDefaultMessage); | ||
538 | struct GNUNET_IDENTITY_Handle *h = cls; | 564 | struct GNUNET_IDENTITY_Handle *h = cls; |
539 | struct GNUNET_IDENTITY_Operation *op; | 565 | struct GNUNET_MQ_MessageHandler handlers[] = { |
540 | struct GNUNET_MessageHeader msg; | 566 | make_identity_result_code_handler (h), |
567 | make_identity_update_handler (h), | ||
568 | make_identity_set_default_handler (h), | ||
569 | GNUNET_MQ_handler_end () | ||
570 | }; | ||
571 | struct GNUNET_MQ_Envelope *env; | ||
572 | struct GNUNET_MessageHeader *msg; | ||
541 | 573 | ||
542 | h->reconnect_task = NULL; | 574 | h->reconnect_task = NULL; |
543 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 575 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
544 | "Connecting to identity service.\n"); | 576 | "Connecting to identity service.\n"); |
545 | GNUNET_assert (NULL == h->client); | 577 | GNUNET_assert (NULL == h->mq); |
546 | h->client = GNUNET_CLIENT_connect ("identity", h->cfg); | 578 | h->mq = GNUNET_CLIENT_connecT (h->cfg, |
547 | GNUNET_assert (NULL != h->client); | 579 | "identity", |
548 | if ( (NULL == h->op_head) || | 580 | handlers, |
549 | (GNUNET_MESSAGE_TYPE_IDENTITY_START != ntohs (h->op_head->msg->type)) ) | 581 | &mq_error_handler, |
550 | { | 582 | h); |
551 | op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_Operation) + | 583 | if (NULL == h->mq) |
552 | sizeof (struct GNUNET_MessageHeader)); | 584 | return; |
553 | op->h = h; | 585 | env = GNUNET_MQ_msg (msg, |
554 | op->msg = (const struct GNUNET_MessageHeader *) &op[1]; | 586 | GNUNET_MESSAGE_TYPE_IDENTITY_START); |
555 | msg.size = htons (sizeof (msg)); | 587 | GNUNET_MQ_send (h->mq, |
556 | msg.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_START); | 588 | env); |
557 | memcpy (&op[1], &msg, sizeof (msg)); | ||
558 | GNUNET_CONTAINER_DLL_insert (h->op_head, | ||
559 | h->op_tail, | ||
560 | op); | ||
561 | } | ||
562 | transmit_next (h); | ||
563 | GNUNET_assert (NULL != h->th); | ||
564 | } | 589 | } |
565 | 590 | ||
566 | 591 | ||
@@ -584,8 +609,12 @@ GNUNET_IDENTITY_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
584 | h->cb = cb; | 609 | h->cb = cb; |
585 | h->cb_cls = cb_cls; | 610 | h->cb_cls = cb_cls; |
586 | h->egos = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_YES); | 611 | h->egos = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_YES); |
587 | h->reconnect_delay = GNUNET_TIME_UNIT_ZERO; | 612 | reconnect (h); |
588 | h->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, h); | 613 | if (NULL == h->mq) |
614 | { | ||
615 | GNUNET_free (h); | ||
616 | return NULL; | ||
617 | } | ||
589 | return h; | 618 | return h; |
590 | } | 619 | } |
591 | 620 | ||
@@ -614,7 +643,7 @@ GNUNET_IDENTITY_ego_get_public_key (const struct GNUNET_IDENTITY_Ego *ego, | |||
614 | struct GNUNET_CRYPTO_EcdsaPublicKey *pk) | 643 | struct GNUNET_CRYPTO_EcdsaPublicKey *pk) |
615 | { | 644 | { |
616 | GNUNET_CRYPTO_ecdsa_key_get_public (ego->pk, | 645 | GNUNET_CRYPTO_ecdsa_key_get_public (ego->pk, |
617 | pk); | 646 | pk); |
618 | } | 647 | } |
619 | 648 | ||
620 | 649 | ||
@@ -622,47 +651,48 @@ GNUNET_IDENTITY_ego_get_public_key (const struct GNUNET_IDENTITY_Ego *ego, | |||
622 | * Obtain the identity that is currently preferred/default | 651 | * Obtain the identity that is currently preferred/default |
623 | * for a service. | 652 | * for a service. |
624 | * | 653 | * |
625 | * @param id identity service to query | 654 | * @param h identity service to query |
626 | * @param service_name for which service is an identity wanted | 655 | * @param service_name for which service is an identity wanted |
627 | * @param cb function to call with the result (will only be called once) | 656 | * @param cb function to call with the result (will only be called once) |
628 | * @param cb_cls closure for @a cb | 657 | * @param cb_cls closure for @a cb |
629 | * @return handle to abort the operation | 658 | * @return handle to abort the operation |
630 | */ | 659 | */ |
631 | struct GNUNET_IDENTITY_Operation * | 660 | struct GNUNET_IDENTITY_Operation * |
632 | GNUNET_IDENTITY_get (struct GNUNET_IDENTITY_Handle *id, | 661 | GNUNET_IDENTITY_get (struct GNUNET_IDENTITY_Handle *h, |
633 | const char *service_name, | 662 | const char *service_name, |
634 | GNUNET_IDENTITY_Callback cb, | 663 | GNUNET_IDENTITY_Callback cb, |
635 | void *cb_cls) | 664 | void *cb_cls) |
636 | { | 665 | { |
637 | struct GNUNET_IDENTITY_Operation *op; | 666 | struct GNUNET_IDENTITY_Operation *op; |
667 | struct GNUNET_MQ_Envelope *env; | ||
638 | struct GNUNET_IDENTITY_GetDefaultMessage *gdm; | 668 | struct GNUNET_IDENTITY_GetDefaultMessage *gdm; |
639 | size_t slen; | 669 | size_t slen; |
640 | 670 | ||
671 | if (NULL == h->mq) | ||
672 | return NULL; | ||
641 | slen = strlen (service_name) + 1; | 673 | slen = strlen (service_name) + 1; |
642 | if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_IDENTITY_GetDefaultMessage)) | 674 | if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_IDENTITY_GetDefaultMessage)) |
643 | { | 675 | { |
644 | GNUNET_break (0); | 676 | GNUNET_break (0); |
645 | return NULL; | 677 | return NULL; |
646 | } | 678 | } |
647 | op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_Operation) + | 679 | op = GNUNET_new (struct GNUNET_IDENTITY_Operation); |
648 | sizeof (struct GNUNET_IDENTITY_GetDefaultMessage) + | 680 | op->h = h; |
649 | slen); | ||
650 | op->h = id; | ||
651 | op->cb = cb; | 681 | op->cb = cb; |
652 | op->cls = cb_cls; | 682 | op->cls = cb_cls; |
653 | gdm = (struct GNUNET_IDENTITY_GetDefaultMessage *) &op[1]; | 683 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, |
654 | gdm->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT); | 684 | h->op_tail, |
655 | gdm->header.size = htons (sizeof (struct GNUNET_IDENTITY_GetDefaultMessage) + | 685 | op); |
656 | slen); | 686 | env = GNUNET_MQ_msg_extra (gdm, |
687 | slen, | ||
688 | GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT); | ||
657 | gdm->name_len = htons (slen); | 689 | gdm->name_len = htons (slen); |
658 | gdm->reserved = htons (0); | 690 | gdm->reserved = htons (0); |
659 | memcpy (&gdm[1], service_name, slen); | 691 | memcpy (&gdm[1], |
660 | op->msg = &gdm->header; | 692 | service_name, |
661 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, | 693 | slen); |
662 | id->op_tail, | 694 | GNUNET_MQ_send (h->mq, |
663 | op); | 695 | env); |
664 | if (NULL == id->th) | ||
665 | transmit_next (id); | ||
666 | return op; | 696 | return op; |
667 | } | 697 | } |
668 | 698 | ||
@@ -670,7 +700,7 @@ GNUNET_IDENTITY_get (struct GNUNET_IDENTITY_Handle *id, | |||
670 | /** | 700 | /** |
671 | * Set the preferred/default identity for a service. | 701 | * Set the preferred/default identity for a service. |
672 | * | 702 | * |
673 | * @param id identity service to inform | 703 | * @param h identity service to inform |
674 | * @param service_name for which service is an identity set | 704 | * @param service_name for which service is an identity set |
675 | * @param ego new default identity to be set for this service | 705 | * @param ego new default identity to be set for this service |
676 | * @param cont function to call once the operation finished | 706 | * @param cont function to call once the operation finished |
@@ -678,42 +708,43 @@ GNUNET_IDENTITY_get (struct GNUNET_IDENTITY_Handle *id, | |||
678 | * @return handle to abort the operation | 708 | * @return handle to abort the operation |
679 | */ | 709 | */ |
680 | struct GNUNET_IDENTITY_Operation * | 710 | struct GNUNET_IDENTITY_Operation * |
681 | GNUNET_IDENTITY_set (struct GNUNET_IDENTITY_Handle *id, | 711 | GNUNET_IDENTITY_set (struct GNUNET_IDENTITY_Handle *h, |
682 | const char *service_name, | 712 | const char *service_name, |
683 | struct GNUNET_IDENTITY_Ego *ego, | 713 | struct GNUNET_IDENTITY_Ego *ego, |
684 | GNUNET_IDENTITY_Continuation cont, | 714 | GNUNET_IDENTITY_Continuation cont, |
685 | void *cont_cls) | 715 | void *cont_cls) |
686 | { | 716 | { |
687 | struct GNUNET_IDENTITY_Operation *op; | 717 | struct GNUNET_IDENTITY_Operation *op; |
718 | struct GNUNET_MQ_Envelope *env; | ||
688 | struct GNUNET_IDENTITY_SetDefaultMessage *sdm; | 719 | struct GNUNET_IDENTITY_SetDefaultMessage *sdm; |
689 | size_t slen; | 720 | size_t slen; |
690 | 721 | ||
722 | if (NULL == h->mq) | ||
723 | return NULL; | ||
691 | slen = strlen (service_name) + 1; | 724 | slen = strlen (service_name) + 1; |
692 | if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_IDENTITY_SetDefaultMessage)) | 725 | if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_IDENTITY_SetDefaultMessage)) |
693 | { | 726 | { |
694 | GNUNET_break (0); | 727 | GNUNET_break (0); |
695 | return NULL; | 728 | return NULL; |
696 | } | 729 | } |
697 | op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_Operation) + | 730 | op = GNUNET_new (struct GNUNET_IDENTITY_Operation); |
698 | sizeof (struct GNUNET_IDENTITY_SetDefaultMessage) + | 731 | op->h = h; |
699 | slen); | ||
700 | op->h = id; | ||
701 | op->cont = cont; | 732 | op->cont = cont; |
702 | op->cls = cont_cls; | 733 | op->cls = cont_cls; |
703 | sdm = (struct GNUNET_IDENTITY_SetDefaultMessage *) &op[1]; | 734 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, |
704 | sdm->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT); | 735 | h->op_tail, |
705 | sdm->header.size = htons (sizeof (struct GNUNET_IDENTITY_SetDefaultMessage) + | 736 | op); |
706 | slen); | 737 | env = GNUNET_MQ_msg_extra (sdm, |
738 | slen, | ||
739 | GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT); | ||
707 | sdm->name_len = htons (slen); | 740 | sdm->name_len = htons (slen); |
708 | sdm->reserved = htons (0); | 741 | sdm->reserved = htons (0); |
709 | sdm->private_key = *ego->pk; | 742 | sdm->private_key = *ego->pk; |
710 | memcpy (&sdm[1], service_name, slen); | 743 | memcpy (&sdm[1], |
711 | op->msg = &sdm->header; | 744 | service_name, |
712 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, | 745 | slen); |
713 | id->op_tail, | 746 | GNUNET_MQ_send (h->mq, |
714 | op); | 747 | env); |
715 | if (NULL == id->th) | ||
716 | transmit_next (id); | ||
717 | return op; | 748 | return op; |
718 | } | 749 | } |
719 | 750 | ||
@@ -721,53 +752,52 @@ GNUNET_IDENTITY_set (struct GNUNET_IDENTITY_Handle *id, | |||
721 | /** | 752 | /** |
722 | * Create a new identity with the given name. | 753 | * Create a new identity with the given name. |
723 | * | 754 | * |
724 | * @param id identity service to use | 755 | * @param h identity service to use |
725 | * @param name desired name | 756 | * @param name desired name |
726 | * @param cont function to call with the result (will only be called once) | 757 | * @param cont function to call with the result (will only be called once) |
727 | * @param cont_cls closure for @a cont | 758 | * @param cont_cls closure for @a cont |
728 | * @return handle to abort the operation | 759 | * @return handle to abort the operation |
729 | */ | 760 | */ |
730 | struct GNUNET_IDENTITY_Operation * | 761 | struct GNUNET_IDENTITY_Operation * |
731 | GNUNET_IDENTITY_create (struct GNUNET_IDENTITY_Handle *id, | 762 | GNUNET_IDENTITY_create (struct GNUNET_IDENTITY_Handle *h, |
732 | const char *name, | 763 | const char *name, |
733 | GNUNET_IDENTITY_Continuation cont, | 764 | GNUNET_IDENTITY_Continuation cont, |
734 | void *cont_cls) | 765 | void *cont_cls) |
735 | { | 766 | { |
736 | struct GNUNET_IDENTITY_Operation *op; | 767 | struct GNUNET_IDENTITY_Operation *op; |
768 | struct GNUNET_MQ_Envelope *env; | ||
737 | struct GNUNET_IDENTITY_CreateRequestMessage *crm; | 769 | struct GNUNET_IDENTITY_CreateRequestMessage *crm; |
738 | struct GNUNET_CRYPTO_EcdsaPrivateKey *pk; | 770 | struct GNUNET_CRYPTO_EcdsaPrivateKey *pk; |
739 | size_t slen; | 771 | size_t slen; |
740 | 772 | ||
773 | if (NULL == h->mq) | ||
774 | return NULL; | ||
741 | slen = strlen (name) + 1; | 775 | slen = strlen (name) + 1; |
742 | pk = GNUNET_CRYPTO_ecdsa_key_create (); | ||
743 | |||
744 | if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_IDENTITY_CreateRequestMessage)) | 776 | if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_IDENTITY_CreateRequestMessage)) |
745 | { | 777 | { |
746 | GNUNET_break (0); | 778 | GNUNET_break (0); |
747 | GNUNET_free (pk); | ||
748 | return NULL; | 779 | return NULL; |
749 | } | 780 | } |
750 | op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_Operation) + | 781 | op = GNUNET_new (struct GNUNET_IDENTITY_Operation); |
751 | sizeof (struct GNUNET_IDENTITY_CreateRequestMessage) + | 782 | op->h = h; |
752 | slen); | ||
753 | op->h = id; | ||
754 | op->cont = cont; | 783 | op->cont = cont; |
755 | op->cls = cont_cls; | 784 | op->cls = cont_cls; |
756 | crm = (struct GNUNET_IDENTITY_CreateRequestMessage *) &op[1]; | 785 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, |
757 | crm->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_CREATE); | 786 | h->op_tail, |
758 | crm->header.size = htons (sizeof (struct GNUNET_IDENTITY_CreateRequestMessage) + | 787 | op); |
759 | slen); | 788 | env = GNUNET_MQ_msg_extra (crm, |
789 | slen, | ||
790 | GNUNET_MESSAGE_TYPE_IDENTITY_CREATE); | ||
760 | crm->name_len = htons (slen); | 791 | crm->name_len = htons (slen); |
761 | crm->reserved = htons (0); | 792 | crm->reserved = htons (0); |
793 | pk = GNUNET_CRYPTO_ecdsa_key_create (); | ||
762 | crm->private_key = *pk; | 794 | crm->private_key = *pk; |
763 | memcpy (&crm[1], name, slen); | ||
764 | op->msg = &crm->header; | ||
765 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, | ||
766 | id->op_tail, | ||
767 | op); | ||
768 | if (NULL == id->th) | ||
769 | transmit_next (id); | ||
770 | GNUNET_free (pk); | 795 | GNUNET_free (pk); |
796 | memcpy (&crm[1], | ||
797 | name, | ||
798 | slen); | ||
799 | GNUNET_MQ_send (h->mq, | ||
800 | env); | ||
771 | return op; | 801 | return op; |
772 | } | 802 | } |
773 | 803 | ||
@@ -775,7 +805,7 @@ GNUNET_IDENTITY_create (struct GNUNET_IDENTITY_Handle *id, | |||
775 | /** | 805 | /** |
776 | * Renames an existing identity. | 806 | * Renames an existing identity. |
777 | * | 807 | * |
778 | * @param id identity service to use | 808 | * @param h identity service to use |
779 | * @param old_name old name | 809 | * @param old_name old name |
780 | * @param new_name desired new name | 810 | * @param new_name desired new name |
781 | * @param cb function to call with the result (will only be called once) | 811 | * @param cb function to call with the result (will only be called once) |
@@ -783,18 +813,21 @@ GNUNET_IDENTITY_create (struct GNUNET_IDENTITY_Handle *id, | |||
783 | * @return handle to abort the operation | 813 | * @return handle to abort the operation |
784 | */ | 814 | */ |
785 | struct GNUNET_IDENTITY_Operation * | 815 | struct GNUNET_IDENTITY_Operation * |
786 | GNUNET_IDENTITY_rename (struct GNUNET_IDENTITY_Handle *id, | 816 | GNUNET_IDENTITY_rename (struct GNUNET_IDENTITY_Handle *h, |
787 | const char *old_name, | 817 | const char *old_name, |
788 | const char *new_name, | 818 | const char *new_name, |
789 | GNUNET_IDENTITY_Continuation cb, | 819 | GNUNET_IDENTITY_Continuation cb, |
790 | void *cb_cls) | 820 | void *cb_cls) |
791 | { | 821 | { |
792 | struct GNUNET_IDENTITY_Operation *op; | 822 | struct GNUNET_IDENTITY_Operation *op; |
823 | struct GNUNET_MQ_Envelope *env; | ||
793 | struct GNUNET_IDENTITY_RenameMessage *grm; | 824 | struct GNUNET_IDENTITY_RenameMessage *grm; |
794 | size_t slen_old; | 825 | size_t slen_old; |
795 | size_t slen_new; | 826 | size_t slen_new; |
796 | char *dst; | 827 | char *dst; |
797 | 828 | ||
829 | if (NULL == h->mq) | ||
830 | return NULL; | ||
798 | slen_old = strlen (old_name) + 1; | 831 | slen_old = strlen (old_name) + 1; |
799 | slen_new = strlen (new_name) + 1; | 832 | slen_new = strlen (new_name) + 1; |
800 | if ( (slen_old >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | 833 | if ( (slen_old >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || |
@@ -804,27 +837,27 @@ GNUNET_IDENTITY_rename (struct GNUNET_IDENTITY_Handle *id, | |||
804 | GNUNET_break (0); | 837 | GNUNET_break (0); |
805 | return NULL; | 838 | return NULL; |
806 | } | 839 | } |
807 | op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_Operation) + | 840 | op = GNUNET_new (struct GNUNET_IDENTITY_Operation); |
808 | sizeof (struct GNUNET_IDENTITY_RenameMessage) + | 841 | op->h = h; |
809 | slen_old + slen_new); | ||
810 | op->h = id; | ||
811 | op->cont = cb; | 842 | op->cont = cb; |
812 | op->cls = cb_cls; | 843 | op->cls = cb_cls; |
813 | grm = (struct GNUNET_IDENTITY_RenameMessage *) &op[1]; | 844 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, |
814 | grm->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_RENAME); | 845 | h->op_tail, |
815 | grm->header.size = htons (sizeof (struct GNUNET_IDENTITY_RenameMessage) + | 846 | op); |
816 | slen_old + slen_new); | 847 | env = GNUNET_MQ_msg_extra (grm, |
848 | slen_old + slen_new, | ||
849 | GNUNET_MESSAGE_TYPE_IDENTITY_RENAME); | ||
817 | grm->old_name_len = htons (slen_old); | 850 | grm->old_name_len = htons (slen_old); |
818 | grm->new_name_len = htons (slen_new); | 851 | grm->new_name_len = htons (slen_new); |
819 | dst = (char *) &grm[1]; | 852 | dst = (char *) &grm[1]; |
820 | memcpy (dst, old_name, slen_old); | 853 | memcpy (dst, |
821 | memcpy (&dst[slen_old], new_name, slen_new); | 854 | old_name, |
822 | op->msg = &grm->header; | 855 | slen_old); |
823 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, | 856 | memcpy (&dst[slen_old], |
824 | id->op_tail, | 857 | new_name, |
825 | op); | 858 | slen_new); |
826 | if (NULL == id->th) | 859 | GNUNET_MQ_send (h->mq, |
827 | transmit_next (id); | 860 | env); |
828 | return op; | 861 | return op; |
829 | } | 862 | } |
830 | 863 | ||
@@ -832,47 +865,48 @@ GNUNET_IDENTITY_rename (struct GNUNET_IDENTITY_Handle *id, | |||
832 | /** | 865 | /** |
833 | * Delete an existing identity. | 866 | * Delete an existing identity. |
834 | * | 867 | * |
835 | * @param id identity service to use | 868 | * @param h identity service to use |
836 | * @param name name of the identity to delete | 869 | * @param name name of the identity to delete |
837 | * @param cb function to call with the result (will only be called once) | 870 | * @param cb function to call with the result (will only be called once) |
838 | * @param cb_cls closure for @a cb | 871 | * @param cb_cls closure for @a cb |
839 | * @return handle to abort the operation | 872 | * @return handle to abort the operation |
840 | */ | 873 | */ |
841 | struct GNUNET_IDENTITY_Operation * | 874 | struct GNUNET_IDENTITY_Operation * |
842 | GNUNET_IDENTITY_delete (struct GNUNET_IDENTITY_Handle *id, | 875 | GNUNET_IDENTITY_delete (struct GNUNET_IDENTITY_Handle *h, |
843 | const char *name, | 876 | const char *name, |
844 | GNUNET_IDENTITY_Continuation cb, | 877 | GNUNET_IDENTITY_Continuation cb, |
845 | void *cb_cls) | 878 | void *cb_cls) |
846 | { | 879 | { |
847 | struct GNUNET_IDENTITY_Operation *op; | 880 | struct GNUNET_IDENTITY_Operation *op; |
881 | struct GNUNET_MQ_Envelope *env; | ||
848 | struct GNUNET_IDENTITY_DeleteMessage *gdm; | 882 | struct GNUNET_IDENTITY_DeleteMessage *gdm; |
849 | size_t slen; | 883 | size_t slen; |
850 | 884 | ||
885 | if (NULL == h->mq) | ||
886 | return NULL; | ||
851 | slen = strlen (name) + 1; | 887 | slen = strlen (name) + 1; |
852 | if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_IDENTITY_DeleteMessage)) | 888 | if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_IDENTITY_DeleteMessage)) |
853 | { | 889 | { |
854 | GNUNET_break (0); | 890 | GNUNET_break (0); |
855 | return NULL; | 891 | return NULL; |
856 | } | 892 | } |
857 | op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_Operation) + | 893 | op = GNUNET_new (struct GNUNET_IDENTITY_Operation); |
858 | sizeof (struct GNUNET_IDENTITY_DeleteMessage) + | 894 | op->h = h; |
859 | slen); | ||
860 | op->h = id; | ||
861 | op->cont = cb; | 895 | op->cont = cb; |
862 | op->cls = cb_cls; | 896 | op->cls = cb_cls; |
863 | gdm = (struct GNUNET_IDENTITY_DeleteMessage *) &op[1]; | 897 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, |
864 | gdm->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_DELETE); | 898 | h->op_tail, |
865 | gdm->header.size = htons (sizeof (struct GNUNET_IDENTITY_DeleteMessage) + | 899 | op); |
866 | slen); | 900 | env = GNUNET_MQ_msg_extra (gdm, |
901 | slen, | ||
902 | GNUNET_MESSAGE_TYPE_IDENTITY_DELETE); | ||
867 | gdm->name_len = htons (slen); | 903 | gdm->name_len = htons (slen); |
868 | gdm->reserved = htons (0); | 904 | gdm->reserved = htons (0); |
869 | memcpy (&gdm[1], name, slen); | 905 | memcpy (&gdm[1], |
870 | op->msg = &gdm->header; | 906 | name, |
871 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, | 907 | slen); |
872 | id->op_tail, | 908 | GNUNET_MQ_send (h->mq, |
873 | op); | 909 | env); |
874 | if (NULL == id->th) | ||
875 | transmit_next (id); | ||
876 | return op; | 910 | return op; |
877 | } | 911 | } |
878 | 912 | ||
@@ -888,71 +922,12 @@ GNUNET_IDENTITY_delete (struct GNUNET_IDENTITY_Handle *id, | |||
888 | void | 922 | void |
889 | GNUNET_IDENTITY_cancel (struct GNUNET_IDENTITY_Operation *op) | 923 | GNUNET_IDENTITY_cancel (struct GNUNET_IDENTITY_Operation *op) |
890 | { | 924 | { |
891 | struct GNUNET_IDENTITY_Handle *h = op->h; | ||
892 | |||
893 | if ( (h->op_head != op) || | ||
894 | (NULL == h->client) ) | ||
895 | { | ||
896 | /* request not active, can simply remove */ | ||
897 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
898 | "Client aborted non-head operation, simply removing it\n"); | ||
899 | GNUNET_CONTAINER_DLL_remove (h->op_head, | ||
900 | h->op_tail, | ||
901 | op); | ||
902 | GNUNET_free (op); | ||
903 | return; | ||
904 | } | ||
905 | if (NULL != h->th) | ||
906 | { | ||
907 | /* request active but not yet with service, can still abort */ | ||
908 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
909 | "Client aborted head operation prior to transmission, aborting it\n"); | ||
910 | GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); | ||
911 | h->th = NULL; | ||
912 | GNUNET_CONTAINER_DLL_remove (h->op_head, | ||
913 | h->op_tail, | ||
914 | op); | ||
915 | GNUNET_free (op); | ||
916 | transmit_next (h); | ||
917 | return; | ||
918 | } | ||
919 | /* request active with service, simply ensure continuations are not called */ | ||
920 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
921 | "Client aborted active request, NULLing continuation\n"); | ||
922 | op->cont = NULL; | 925 | op->cont = NULL; |
923 | op->cb = NULL; | 926 | op->cb = NULL; |
924 | } | 927 | } |
925 | 928 | ||
926 | 929 | ||
927 | /** | 930 | /** |
928 | * Free ego from hash map. | ||
929 | * | ||
930 | * @param cls identity service handle | ||
931 | * @param key unused | ||
932 | * @param value ego to free | ||
933 | * @return #GNUNET_OK (continue to iterate) | ||
934 | */ | ||
935 | static int | ||
936 | free_ego (void *cls, | ||
937 | const struct GNUNET_HashCode *key, | ||
938 | void *value) | ||
939 | { | ||
940 | struct GNUNET_IDENTITY_Handle *h = cls; | ||
941 | struct GNUNET_IDENTITY_Ego *ego = value; | ||
942 | |||
943 | if (NULL != h->cb) | ||
944 | h->cb (h->cb_cls, | ||
945 | ego, | ||
946 | &ego->ctx, | ||
947 | NULL); | ||
948 | GNUNET_free (ego->pk); | ||
949 | GNUNET_free (ego->name); | ||
950 | GNUNET_free (ego); | ||
951 | return GNUNET_OK; | ||
952 | } | ||
953 | |||
954 | |||
955 | /** | ||
956 | * Disconnect from identity service | 931 | * Disconnect from identity service |
957 | * | 932 | * |
958 | * @param h handle to destroy | 933 | * @param h handle to destroy |
@@ -968,11 +943,6 @@ GNUNET_IDENTITY_disconnect (struct GNUNET_IDENTITY_Handle *h) | |||
968 | GNUNET_SCHEDULER_cancel (h->reconnect_task); | 943 | GNUNET_SCHEDULER_cancel (h->reconnect_task); |
969 | h->reconnect_task = NULL; | 944 | h->reconnect_task = NULL; |
970 | } | 945 | } |
971 | if (NULL != h->th) | ||
972 | { | ||
973 | GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); | ||
974 | h->th = NULL; | ||
975 | } | ||
976 | if (NULL != h->egos) | 946 | if (NULL != h->egos) |
977 | { | 947 | { |
978 | GNUNET_CONTAINER_multihashmap_iterate (h->egos, | 948 | GNUNET_CONTAINER_multihashmap_iterate (h->egos, |
@@ -989,10 +959,10 @@ GNUNET_IDENTITY_disconnect (struct GNUNET_IDENTITY_Handle *h) | |||
989 | op); | 959 | op); |
990 | GNUNET_free (op); | 960 | GNUNET_free (op); |
991 | } | 961 | } |
992 | if (NULL != h->client) | 962 | if (NULL != h->mq) |
993 | { | 963 | { |
994 | GNUNET_CLIENT_disconnect (h->client); | 964 | GNUNET_MQ_destroy (h->mq); |
995 | h->client = NULL; | 965 | h->mq = NULL; |
996 | } | 966 | } |
997 | GNUNET_free (h); | 967 | GNUNET_free (h); |
998 | } | 968 | } |