aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/reclaim/reclaim_api.c875
1 files changed, 438 insertions, 437 deletions
diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c
index 8c97ba9a2..21c870a37 100644
--- a/src/reclaim/reclaim_api.c
+++ b/src/reclaim/reclaim_api.c
@@ -292,513 +292,514 @@ struct GNUNET_RECLAIM_Handle
292 */ 292 */
293 struct GNUNET_SCHEDULER_Task *reconnect_task; 293 struct GNUNET_SCHEDULER_Task *reconnect_task;
294 294
295 /**
296 * Time for next connect retry.
297 */
298 struct GNUNET_TIME_Relative reconnect_backoff;
299
300 /**
301 * Connection to service (if available).
302 */
303 struct GNUNET_MQ_Handle *mq;
304
305 /**
306 * Request Id generator. Incremented by one for each request.
307 */
308 uint32_t r_id_gen;
309
310 /**
311 * Are we polling for incoming messages right now?
312 */
313 int in_receive;
314 };
315
316
295 /** 317 /**
296 * Time for next connect retry. 318 * Try again to connect to the service.
319 *
320 * @param h handle to the reclaim service.
297 */ 321 */
298 struct GNUNET_TIME_Relative reconnect_backoff; 322 static void
323 reconnect (struct GNUNET_RECLAIM_Handle *h);
324
299 325
300 /** 326 /**
301 * Connection to service (if available). 327 * Reconnect
328 *
329 * @param cls the handle
302 */ 330 */
303 struct GNUNET_MQ_Handle *mq; 331 static void
332 reconnect_task (void *cls)
333 {
334 struct GNUNET_RECLAIM_Handle *handle = cls;
335
336 handle->reconnect_task = NULL;
337 reconnect (handle);
338 }
339
304 340
305 /** 341 /**
306 * Request Id generator. Incremented by one for each request. 342 * Disconnect from service and then reconnect.
343 *
344 * @param handle our service
307 */ 345 */
308 uint32_t r_id_gen; 346 static void
347 force_reconnect (struct GNUNET_RECLAIM_Handle *handle)
348 {
349 GNUNET_MQ_destroy (handle->mq);
350 handle->mq = NULL;
351 handle->reconnect_backoff =
352 GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
353 handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (
354 handle->reconnect_backoff, &reconnect_task, handle);
355 }
356
309 357
310 /** 358 /**
311 * Are we polling for incoming messages right now? 359 * Free @a it.
360 *
361 * @param it entry to free
312 */ 362 */
313 int in_receive; 363 static void
314}; 364 free_it (struct GNUNET_RECLAIM_AttributeIterator *it)
365 {
366 struct GNUNET_RECLAIM_Handle *h = it->h;
315 367
368 GNUNET_CONTAINER_DLL_remove (h->it_head, h->it_tail, it);
369 if (NULL != it->env)
370 GNUNET_MQ_discard (it->env);
371 GNUNET_free (it);
372 }
316 373
317/** 374 /**
318 * Try again to connect to the service. 375 * Free @a op
319 * 376 *
320 * @param h handle to the reclaim service. 377 * @param op the operation to free
321 */ 378 */
322static void 379 static void
323reconnect (struct GNUNET_RECLAIM_Handle *h); 380 free_op (struct GNUNET_RECLAIM_Operation *op)
381 {
382 if (NULL == op)
383 return;
384 if (NULL != op->env)
385 GNUNET_MQ_discard (op->env);
386 GNUNET_free (op);
387 }
324 388
325 389
326/** 390 /**
327 * Reconnect 391 * Generic error handler, called with the appropriate error code and
328 * 392 * the same closure specified at the creation of the message queue.
329 * @param cls the handle 393 * Not every message queue implementation supports an error handler.
330 */ 394 *
331static void 395 * @param cls closure with the `struct GNUNET_GNS_Handle *`
332reconnect_task (void *cls) 396 * @param error error code
333{ 397 */
334 struct GNUNET_RECLAIM_Handle *handle = cls; 398 static void
399 mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
400 {
401 struct GNUNET_RECLAIM_Handle *handle = cls;
402 force_reconnect (handle);
403 }
335 404
336 handle->reconnect_task = NULL;
337 reconnect (handle);
338}
339 405
406 /**
407 * Handle an incoming message of type
408 * #GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE
409 *
410 * @param cls
411 * @param msg the message we received
412 */
413 static void
414 handle_success_response (void *cls, const struct SuccessResultMessage *msg)
415 {
416 struct GNUNET_RECLAIM_Handle *h = cls;
417 struct GNUNET_RECLAIM_Operation *op;
418 uint32_t r_id = ntohl (msg->id);
419 int res;
420 const char *emsg;
421
422 for (op = h->op_head; NULL != op; op = op->next)
423 if (op->r_id == r_id)
424 break;
425 if (NULL == op)
426 return;
340 427
341/** 428 res = ntohl (msg->op_result);
342 * Disconnect from service and then reconnect. 429 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received SUCCESS_RESPONSE with result %d\n",
343 * 430 res);
344 * @param handle our service 431
345 */ 432 /* TODO: add actual error message to response... */
346static void 433 if (GNUNET_SYSERR == res)
347force_reconnect (struct GNUNET_RECLAIM_Handle *handle) 434 emsg = _ ("failed to store record\n");
348{ 435 else
349 GNUNET_MQ_destroy (handle->mq); 436 emsg = NULL;
350 handle->mq = NULL; 437 if (NULL != op->as_cb)
351 handle->reconnect_backoff = 438 op->as_cb (op->cls, res, emsg);
352 GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff); 439 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
353 handle->reconnect_task = GNUNET_SCHEDULER_add_delayed ( 440 free_op (op);
354 handle->reconnect_backoff, &reconnect_task, handle); 441 }
355}
356 442
357 443
358/** 444 /**
359 * Free @a it. 445 * Handle an incoming message of type
360 * 446 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
361 * @param it entry to free 447 *
362 */ 448 * @param cls
363static void 449 * @param msg the message we received
364free_it (struct GNUNET_RECLAIM_AttributeIterator *it) 450 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
365{ 451 */
366 struct GNUNET_RECLAIM_Handle *h = it->h; 452 static int
453 check_consume_ticket_result (void *cls,
454 const struct ConsumeTicketResultMessage *msg)
455 {
456 size_t msg_len;
457 size_t attrs_len;
367 458
368 GNUNET_CONTAINER_DLL_remove (h->it_head, h->it_tail, it); 459 msg_len = ntohs (msg->header.size);
369 if (NULL != it->env) 460 attrs_len = ntohs (msg->attrs_len);
370 GNUNET_MQ_discard (it->env); 461 if (msg_len != sizeof (struct ConsumeTicketResultMessage) + attrs_len) {
371 GNUNET_free (it); 462 GNUNET_break (0);
372} 463 return GNUNET_SYSERR;
464 }
465 return GNUNET_OK;
466 }
373 467
374/**
375 * Free @a op
376 *
377 * @param op the operation to free
378 */
379static void
380free_op (struct GNUNET_RECLAIM_Operation *op)
381{
382 if (NULL == op)
383 return;
384 if (NULL != op->env)
385 GNUNET_MQ_discard (op->env);
386 GNUNET_free (op);
387}
388 468
469 /**
470 * Handle an incoming message of type
471 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
472 *
473 * @param cls
474 * @param msg the message we received
475 */
476 static void
477 handle_consume_ticket_result (void *cls,
478 const struct ConsumeTicketResultMessage *msg)
479 {
480 struct GNUNET_RECLAIM_Handle *h = cls;
481 struct GNUNET_RECLAIM_Operation *op;
482 size_t attrs_len;
483 uint32_t r_id = ntohl (msg->id);
389 484
390/** 485 attrs_len = ntohs (msg->attrs_len);
391 * Generic error handler, called with the appropriate error code and 486 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n");
392 * the same closure specified at the creation of the message queue.
393 * Not every message queue implementation supports an error handler.
394 *
395 * @param cls closure with the `struct GNUNET_GNS_Handle *`
396 * @param error error code
397 */
398static void
399mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
400{
401 struct GNUNET_RECLAIM_Handle *handle = cls;
402 force_reconnect (handle);
403}
404 487
405 488
406/** 489 for (op = h->op_head; NULL != op; op = op->next)
407 * Handle an incoming message of type 490 if (op->r_id == r_id)
408 * #GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE 491 break;
409 * 492 if (NULL == op)
410 * @param cls 493 return;
411 * @param msg the message we received
412 */
413static void
414handle_success_response (void *cls, const struct SuccessResultMessage *msg)
415{
416 struct GNUNET_RECLAIM_Handle *h = cls;
417 struct GNUNET_RECLAIM_Operation *op;
418 uint32_t r_id = ntohl (msg->id);
419 int res;
420 const char *emsg;
421
422 for (op = h->op_head; NULL != op; op = op->next)
423 if (op->r_id == r_id)
424 break;
425 if (NULL == op)
426 return;
427
428 res = ntohl (msg->op_result);
429 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received SUCCESS_RESPONSE with result %d\n",
430 res);
431
432 /* TODO: add actual error message to response... */
433 if (GNUNET_SYSERR == res)
434 emsg = _ ("failed to store record\n");
435 else
436 emsg = NULL;
437 if (NULL != op->as_cb)
438 op->as_cb (op->cls, res, emsg);
439 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
440 free_op (op);
441}
442 494
495 {
496 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
497 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
498 attrs =
499 GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char *)&msg[1], attrs_len);
500 if (NULL != op->ar_cb) {
501 if (NULL == attrs) {
502 op->ar_cb (op->cls, &msg->identity, NULL);
503 } else {
504 for (le = attrs->list_head; NULL != le; le = le->next)
505 op->ar_cb (op->cls, &msg->identity, le->claim);
506 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs);
507 attrs = NULL;
508 }
509 op->ar_cb (op->cls, NULL, NULL);
510 }
511 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
512 free_op (op);
513 GNUNET_free_non_null (attrs);
514 return;
515 }
516 GNUNET_assert (0);
517 }
443 518
444/**
445 * Handle an incoming message of type
446 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
447 *
448 * @param cls
449 * @param msg the message we received
450 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
451 */
452static int
453check_consume_ticket_result (void *cls,
454 const struct ConsumeTicketResultMessage *msg)
455{
456 size_t msg_len;
457 size_t attrs_len;
458 519
459 msg_len = ntohs (msg->header.size); 520 /**
460 attrs_len = ntohs (msg->attrs_len); 521 * Handle an incoming message of type
461 if (msg_len != sizeof (struct ConsumeTicketResultMessage) + attrs_len) { 522 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
462 GNUNET_break (0); 523 *
463 return GNUNET_SYSERR; 524 * @param cls
525 * @param msg the message we received
526 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
527 */
528 static int
529 check_attribute_result (void *cls, const struct AttributeResultMessage *msg)
530 {
531 size_t msg_len;
532 size_t attr_len;
533
534 msg_len = ntohs (msg->header.size);
535 attr_len = ntohs (msg->attr_len);
536 if (msg_len != sizeof (struct AttributeResultMessage) + attr_len) {
537 GNUNET_break (0);
538 return GNUNET_SYSERR;
539 }
540 return GNUNET_OK;
464 } 541 }
465 return GNUNET_OK;
466}
467 542
468 543
469/** 544 /**
470 * Handle an incoming message of type 545 * Handle an incoming message of type
471 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT 546 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
472 * 547 *
473 * @param cls 548 * @param cls
474 * @param msg the message we received 549 * @param msg the message we received
475 */ 550 */
476static void 551 static void
477handle_consume_ticket_result (void *cls, 552 handle_attribute_result (void *cls, const struct AttributeResultMessage *msg)
478 const struct ConsumeTicketResultMessage *msg) 553 {
479{ 554 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
480 struct GNUNET_RECLAIM_Handle *h = cls; 555 struct GNUNET_RECLAIM_Handle *h = cls;
481 struct GNUNET_RECLAIM_Operation *op; 556 struct GNUNET_RECLAIM_AttributeIterator *it;
482 size_t attrs_len; 557 struct GNUNET_RECLAIM_Operation *op;
483 uint32_t r_id = ntohl (msg->id); 558 size_t attr_len;
559 uint32_t r_id = ntohl (msg->id);
560
561 attr_len = ntohs (msg->attr_len);
562 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n");
563
564
565 for (it = h->it_head; NULL != it; it = it->next)
566 if (it->r_id == r_id)
567 break;
568 for (op = h->op_head; NULL != op; op = op->next)
569 if (op->r_id == r_id)
570 break;
571 if ((NULL == it) && (NULL == op))
572 return;
484 573
485 attrs_len = ntohs (msg->attrs_len); 574 if ((0 ==
486 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n"); 575 (memcmp (&msg->identity, &identity_dummy, sizeof (identity_dummy))))) {
576 if ((NULL == it) && (NULL == op)) {
577 GNUNET_break (0);
578 force_reconnect (h);
579 return;
580 }
581 if (NULL != it) {
582 if (NULL != it->finish_cb)
583 it->finish_cb (it->finish_cb_cls);
584 free_it (it);
585 }
586 if (NULL != op) {
587 if (NULL != op->ar_cb)
588 op->ar_cb (op->cls, NULL, NULL);
589 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
590 free_op (op);
591 }
592 return;
593 }
487 594
595 {
596 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
597 attr = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *)&msg[1], attr_len);
598 if (NULL != it) {
599 if (NULL != it->proc)
600 it->proc (it->proc_cls, &msg->identity, attr);
601 } else if (NULL != op) {
602 if (NULL != op->ar_cb)
603 op->ar_cb (op->cls, &msg->identity, attr);
604 }
605 GNUNET_free (attr);
606 return;
607 }
608 GNUNET_assert (0);
609 }
488 610
489 for (op = h->op_head; NULL != op; op = op->next)
490 if (op->r_id == r_id)
491 break;
492 if (NULL == op)
493 return;
494 611
612 /**
613 * Handle an incoming message of type
614 * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT
615 *
616 * @param cls
617 * @param msg the message we received
618 */
619 static void
620 handle_ticket_result (void *cls, const struct TicketResultMessage *msg)
495 { 621 {
496 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs; 622 struct GNUNET_RECLAIM_Handle *handle = cls;
497 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; 623 struct GNUNET_RECLAIM_Operation *op;
498 attrs = 624 struct GNUNET_RECLAIM_TicketIterator *it;
499 GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char *)&msg[1], attrs_len); 625 uint32_t r_id = ntohl (msg->id);
500 if (NULL != op->ar_cb) { 626 static const struct GNUNET_RECLAIM_Ticket ticket;
501 if (NULL == attrs) { 627 for (op = handle->op_head; NULL != op; op = op->next)
502 op->ar_cb (op->cls, &msg->identity, NULL); 628 if (op->r_id == r_id)
629 break;
630 for (it = handle->ticket_it_head; NULL != it; it = it->next)
631 if (it->r_id == r_id)
632 break;
633 if ((NULL == op) && (NULL == it))
634 return;
635 if (NULL != op) {
636 GNUNET_CONTAINER_DLL_remove (handle->op_head, handle->op_tail, op);
637 if (0 == memcmp (&msg->ticket, &ticket, sizeof (struct GNUNET_RECLAIM_Ticket)))
638 {
639 if (NULL != op->tr_cb)
640 op->tr_cb (op->cls, NULL);
641 } else {
642 if (NULL != op->tr_cb)
643 op->tr_cb (op->cls, &msg->ticket);
644 }
645 free_op (op);
646 return;
647 } else if (NULL != it) {
648 if (0 == memcmp (&msg->ticket, &ticket, sizeof (struct GNUNET_RECLAIM_Ticket)))
649 {
650 GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
651 handle->ticket_it_tail, it);
652 it->finish_cb (it->finish_cb_cls);
653 GNUNET_free (it);
503 } else { 654 } else {
504 for (le = attrs->list_head; NULL != le; le = le->next) 655 if (NULL != it->tr_cb)
505 op->ar_cb (op->cls, &msg->identity, le->claim); 656 it->tr_cb (it->cls, &msg->ticket);
506 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs);
507 } 657 }
508 op->ar_cb (op->cls, NULL, NULL); 658 return;
509 } 659 }
510 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
511 free_op (op);
512 GNUNET_free_non_null (attrs);
513 return;
514 }
515 GNUNET_assert (0);
516}
517
518
519/**
520 * Handle an incoming message of type
521 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
522 *
523 * @param cls
524 * @param msg the message we received
525 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
526 */
527static int
528check_attribute_result (void *cls, const struct AttributeResultMessage *msg)
529{
530 size_t msg_len;
531 size_t attr_len;
532
533 msg_len = ntohs (msg->header.size);
534 attr_len = ntohs (msg->attr_len);
535 if (msg_len != sizeof (struct AttributeResultMessage) + attr_len) {
536 GNUNET_break (0); 660 GNUNET_break (0);
537 return GNUNET_SYSERR;
538 } 661 }
539 return GNUNET_OK;
540}
541 662
542 663
543/** 664 /**
544 * Handle an incoming message of type 665 * Handle an incoming message of type
545 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT 666 * #GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT
546 * 667 *
547 * @param cls 668 * @param cls
548 * @param msg the message we received 669 * @param msg the message we received
549 */ 670 */
550static void 671 static void
551handle_attribute_result (void *cls, const struct AttributeResultMessage *msg) 672 handle_revoke_ticket_result (void *cls,
552{ 673 const struct RevokeTicketResultMessage *msg)
553 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy; 674 {
554 struct GNUNET_RECLAIM_Handle *h = cls; 675 struct GNUNET_RECLAIM_Handle *h = cls;
555 struct GNUNET_RECLAIM_AttributeIterator *it; 676 struct GNUNET_RECLAIM_Operation *op;
556 struct GNUNET_RECLAIM_Operation *op; 677 uint32_t r_id = ntohl (msg->id);
557 size_t attr_len; 678 int32_t success;
558 uint32_t r_id = ntohl (msg->id);
559
560 attr_len = ntohs (msg->attr_len);
561 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n");
562 679
680 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing revocation result.\n");
563 681
564 for (it = h->it_head; NULL != it; it = it->next)
565 if (it->r_id == r_id)
566 break;
567 for (op = h->op_head; NULL != op; op = op->next)
568 if (op->r_id == r_id)
569 break;
570 if ((NULL == it) && (NULL == op))
571 return;
572 682
573 if ((0 == 683 for (op = h->op_head; NULL != op; op = op->next)
574 (memcmp (&msg->identity, &identity_dummy, sizeof (identity_dummy))))) { 684 if (op->r_id == r_id)
575 if ((NULL == it) && (NULL == op)) { 685 break;
576 GNUNET_break (0); 686 if (NULL == op)
577 force_reconnect (h);
578 return; 687 return;
579 } 688 success = ntohl (msg->success);
580 if (NULL != it) { 689 {
581 if (NULL != it->finish_cb) 690 if (NULL != op->rvk_cb) {
582 it->finish_cb (it->finish_cb_cls); 691 op->rvk_cb (op->cls, success, NULL);
583 free_it (it); 692 }
584 }
585 if (NULL != op) {
586 if (NULL != op->ar_cb)
587 op->ar_cb (op->cls, NULL, NULL);
588 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op); 693 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
589 free_op (op); 694 free_op (op);
695 return;
590 } 696 }
591 return; 697 GNUNET_assert (0);
592 } 698 }
593 699
700
701 /**
702 * Try again to connect to the service.
703 *
704 * @param h handle to the reclaim service.
705 */
706 static void
707 reconnect (struct GNUNET_RECLAIM_Handle *h)
594 { 708 {
595 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr; 709 struct GNUNET_MQ_MessageHandler handlers[] = {
596 attr = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *)&msg[1], attr_len); 710 GNUNET_MQ_hd_fixed_size (success_response,
597 if (NULL != it) { 711 GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE,
598 if (NULL != it->proc) 712 struct SuccessResultMessage, h),
599 it->proc (it->proc_cls, &msg->identity, attr); 713 GNUNET_MQ_hd_var_size (attribute_result,
600 } else if (NULL != op) { 714 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT,
601 if (NULL != op->ar_cb) 715 struct AttributeResultMessage, h),
602 op->ar_cb (op->cls, &msg->identity, attr); 716 GNUNET_MQ_hd_fixed_size (ticket_result,
603 } 717 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT,
604 GNUNET_free (attr); 718 struct TicketResultMessage, h),
605 return; 719 GNUNET_MQ_hd_var_size (consume_ticket_result,
720 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT,
721 struct ConsumeTicketResultMessage, h),
722 GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
723 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT,
724 struct RevokeTicketResultMessage, h),
725 GNUNET_MQ_handler_end ()};
726 struct GNUNET_RECLAIM_Operation *op;
727
728 GNUNET_assert (NULL == h->mq);
729 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to reclaim service.\n");
730
731 h->mq =
732 GNUNET_CLIENT_connect (h->cfg, "reclaim", handlers, &mq_error_handler, h);
733 if (NULL == h->mq)
734 return;
735 for (op = h->op_head; NULL != op; op = op->next)
736 GNUNET_MQ_send_copy (h->mq, op->env);
606 } 737 }
607 GNUNET_assert (0);
608}
609 738
610 739
611/** 740 /**
612 * Handle an incoming message of type 741 * Connect to the reclaim service.
613 * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT 742 *
614 * 743 * @param cfg the configuration to use
615 * @param cls 744 * @return handle to use
616 * @param msg the message we received 745 */
617 */ 746 struct GNUNET_RECLAIM_Handle *
618static void 747 GNUNET_RECLAIM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
619handle_ticket_result (void *cls, const struct TicketResultMessage *msg) 748 {
620{ 749 struct GNUNET_RECLAIM_Handle *h;
621 struct GNUNET_RECLAIM_Handle *handle = cls; 750
622 struct GNUNET_RECLAIM_Operation *op; 751 h = GNUNET_new (struct GNUNET_RECLAIM_Handle);
623 struct GNUNET_RECLAIM_TicketIterator *it; 752 h->cfg = cfg;
624 uint32_t r_id = ntohl (msg->id); 753 reconnect (h);
625 static const struct GNUNET_RECLAIM_Ticket ticket; 754 if (NULL == h->mq) {
626 for (op = handle->op_head; NULL != op; op = op->next) 755 GNUNET_free (h);
627 if (op->r_id == r_id) 756 return NULL;
628 break;
629 for (it = handle->ticket_it_head; NULL != it; it = it->next)
630 if (it->r_id == r_id)
631 break;
632 if ((NULL == op) && (NULL == it))
633 return;
634 if (NULL != op) {
635 GNUNET_CONTAINER_DLL_remove (handle->op_head, handle->op_tail, op);
636 if (0 == memcmp (&msg->ticket, &ticket, sizeof (struct GNUNET_RECLAIM_Ticket)))
637 {
638 if (NULL != op->tr_cb)
639 op->tr_cb (op->cls, NULL);
640 } else {
641 if (NULL != op->tr_cb)
642 op->tr_cb (op->cls, &msg->ticket);
643 }
644 free_op (op);
645 return;
646 } else if (NULL != it) {
647 if (0 == memcmp (&msg->ticket, &ticket, sizeof (struct GNUNET_RECLAIM_Ticket)))
648 {
649 GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
650 handle->ticket_it_tail, it);
651 it->finish_cb (it->finish_cb_cls);
652 GNUNET_free (it);
653 } else {
654 if (NULL != it->tr_cb)
655 it->tr_cb (it->cls, &msg->ticket);
656 } 757 }
657 return; 758 return h;
658 } 759 }
659 GNUNET_break (0);
660}
661
662
663/**
664 * Handle an incoming message of type
665 * #GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT
666 *
667 * @param cls
668 * @param msg the message we received
669 */
670static void
671handle_revoke_ticket_result (void *cls,
672 const struct RevokeTicketResultMessage *msg)
673{
674 struct GNUNET_RECLAIM_Handle *h = cls;
675 struct GNUNET_RECLAIM_Operation *op;
676 uint32_t r_id = ntohl (msg->id);
677 int32_t success;
678 760
679 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing revocation result.\n");
680 761
681 762 /**
682 for (op = h->op_head; NULL != op; op = op->next) 763 * Cancel an operation. Note that the operation MAY still
683 if (op->r_id == r_id) 764 * be executed; this merely cancels the continuation; if the request
684 break; 765 * was already transmitted, the service may still choose to complete
685 if (NULL == op) 766 * the operation.
686 return; 767 *
687 success = ntohl (msg->success); 768 * @param op operation to cancel
769 */
770 void
771 GNUNET_RECLAIM_cancel (struct GNUNET_RECLAIM_Operation *op)
688 { 772 {
689 if (NULL != op->rvk_cb) { 773 struct GNUNET_RECLAIM_Handle *h = op->h;
690 op->rvk_cb (op->cls, success, NULL); 774
691 }
692 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op); 775 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
693 free_op (op); 776 free_op (op);
694 return;
695 } 777 }
696 GNUNET_assert (0);
697}
698
699 778
700/**
701 * Try again to connect to the service.
702 *
703 * @param h handle to the reclaim service.
704 */
705static void
706reconnect (struct GNUNET_RECLAIM_Handle *h)
707{
708 struct GNUNET_MQ_MessageHandler handlers[] = {
709 GNUNET_MQ_hd_fixed_size (success_response,
710 GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE,
711 struct SuccessResultMessage, h),
712 GNUNET_MQ_hd_var_size (attribute_result,
713 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT,
714 struct AttributeResultMessage, h),
715 GNUNET_MQ_hd_fixed_size (ticket_result,
716 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT,
717 struct TicketResultMessage, h),
718 GNUNET_MQ_hd_var_size (consume_ticket_result,
719 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT,
720 struct ConsumeTicketResultMessage, h),
721 GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
722 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT,
723 struct RevokeTicketResultMessage, h),
724 GNUNET_MQ_handler_end ()};
725 struct GNUNET_RECLAIM_Operation *op;
726
727 GNUNET_assert (NULL == h->mq);
728 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to reclaim service.\n");
729
730 h->mq =
731 GNUNET_CLIENT_connect (h->cfg, "reclaim", handlers, &mq_error_handler, h);
732 if (NULL == h->mq)
733 return;
734 for (op = h->op_head; NULL != op; op = op->next)
735 GNUNET_MQ_send_copy (h->mq, op->env);
736}
737
738
739/**
740 * Connect to the reclaim service.
741 *
742 * @param cfg the configuration to use
743 * @return handle to use
744 */
745struct GNUNET_RECLAIM_Handle *
746GNUNET_RECLAIM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
747{
748 struct GNUNET_RECLAIM_Handle *h;
749 779
750 h = GNUNET_new (struct GNUNET_RECLAIM_Handle); 780 /**
751 h->cfg = cfg; 781 * Disconnect from service
752 reconnect (h); 782 *
753 if (NULL == h->mq) { 783 * @param h handle to destroy
784 */
785 void
786 GNUNET_RECLAIM_disconnect (struct GNUNET_RECLAIM_Handle *h)
787 {
788 GNUNET_assert (NULL != h);
789 if (NULL != h->mq) {
790 GNUNET_MQ_destroy (h->mq);
791 h->mq = NULL;
792 }
793 if (NULL != h->reconnect_task) {
794 GNUNET_SCHEDULER_cancel (h->reconnect_task);
795 h->reconnect_task = NULL;
796 }
797 GNUNET_assert (NULL == h->op_head);
754 GNUNET_free (h); 798 GNUNET_free (h);
755 return NULL;
756 }
757 return h;
758}
759
760
761/**
762 * Cancel an operation. Note that the operation MAY still
763 * be executed; this merely cancels the continuation; if the request
764 * was already transmitted, the service may still choose to complete
765 * the operation.
766 *
767 * @param op operation to cancel
768 */
769void
770GNUNET_RECLAIM_cancel (struct GNUNET_RECLAIM_Operation *op)
771{
772 struct GNUNET_RECLAIM_Handle *h = op->h;
773
774 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
775 free_op (op);
776}
777
778
779/**
780 * Disconnect from service
781 *
782 * @param h handle to destroy
783 */
784void
785GNUNET_RECLAIM_disconnect (struct GNUNET_RECLAIM_Handle *h)
786{
787 GNUNET_assert (NULL != h);
788 if (NULL != h->mq) {
789 GNUNET_MQ_destroy (h->mq);
790 h->mq = NULL;
791 }
792 if (NULL != h->reconnect_task) {
793 GNUNET_SCHEDULER_cancel (h->reconnect_task);
794 h->reconnect_task = NULL;
795 } 799 }
796 GNUNET_assert (NULL == h->op_head);
797 GNUNET_free (h);
798}
799 800
800/** 801 /**
801 * Store an attribute. If the attribute is already present, 802 * Store an attribute. If the attribute is already present,
802 * it is replaced with the new attribute. 803 * it is replaced with the new attribute.
803 * 804 *
804 * @param h handle to the re:claimID service 805 * @param h handle to the re:claimID service