aboutsummaryrefslogtreecommitdiff
path: root/src/identity/identity_api.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-06-21 22:27:17 +0000
committerChristian Grothoff <christian@grothoff.org>2016-06-21 22:27:17 +0000
commitdd9ed7931e52705b216c346127108520c5e4460b (patch)
tree3091fc4c7d2eaa93c5cd746e3d7ac155c2ff815e /src/identity/identity_api.c
parent028d6d5d44aa4affbc5e78d5bb26a9254fe7a13b (diff)
downloadgnunet-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.c872
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 */
208static int
209free_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);
208static void 237static void
209reschedule_connect (struct GNUNET_IDENTITY_Handle *h) 238reschedule_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 */
240static void 287static void
241message_handler (void *cls, 288mq_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 */
305static int
306check_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); 329static void
316 return; 330handle_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 */
452static void 364static int
453transmit_next (struct GNUNET_IDENTITY_Handle *h); 365check_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 */
464static size_t 389static void
465send_next_message (void *cls, 390handle_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 */
476static int
477check_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 */
511static void 503static void
512transmit_next (struct GNUNET_IDENTITY_Handle *h) 504handle_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)
535static void 552static void
536reconnect (void *cls) 553reconnect (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 */
631struct GNUNET_IDENTITY_Operation * 660struct GNUNET_IDENTITY_Operation *
632GNUNET_IDENTITY_get (struct GNUNET_IDENTITY_Handle *id, 661GNUNET_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 */
680struct GNUNET_IDENTITY_Operation * 710struct GNUNET_IDENTITY_Operation *
681GNUNET_IDENTITY_set (struct GNUNET_IDENTITY_Handle *id, 711GNUNET_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 */
730struct GNUNET_IDENTITY_Operation * 761struct GNUNET_IDENTITY_Operation *
731GNUNET_IDENTITY_create (struct GNUNET_IDENTITY_Handle *id, 762GNUNET_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 */
785struct GNUNET_IDENTITY_Operation * 815struct GNUNET_IDENTITY_Operation *
786GNUNET_IDENTITY_rename (struct GNUNET_IDENTITY_Handle *id, 816GNUNET_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 */
841struct GNUNET_IDENTITY_Operation * 874struct GNUNET_IDENTITY_Operation *
842GNUNET_IDENTITY_delete (struct GNUNET_IDENTITY_Handle *id, 875GNUNET_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,
888void 922void
889GNUNET_IDENTITY_cancel (struct GNUNET_IDENTITY_Operation *op) 923GNUNET_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 */
935static int
936free_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}