diff options
-rw-r--r-- | src/reclaim/reclaim_api.c | 875 |
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 | */ |
322 | static void | 379 | static void |
323 | reconnect (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 | * |
331 | static void | 395 | * @param cls closure with the `struct GNUNET_GNS_Handle *` |
332 | reconnect_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... */ |
346 | static void | 433 | if (GNUNET_SYSERR == res) |
347 | force_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 |
363 | static void | 449 | * @param msg the message we received |
364 | free_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 | */ | ||
379 | static void | ||
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 | } | ||
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 | */ | ||
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 | } | ||
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 | */ | ||
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; | ||
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 | */ | ||
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; | ||
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 | */ |
476 | static void | 551 | static void |
477 | handle_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 | */ | ||
527 | static int | ||
528 | check_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 | */ |
550 | static void | 671 | static void |
551 | handle_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 * |
618 | static void | 747 | GNUNET_RECLAIM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) |
619 | handle_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 | */ | ||
670 | static void | ||
671 | handle_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 | */ | ||
705 | static void | ||
706 | reconnect (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 | */ | ||
745 | struct GNUNET_RECLAIM_Handle * | ||
746 | GNUNET_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 | */ | ||
769 | void | ||
770 | GNUNET_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 | */ | ||
784 | void | ||
785 | GNUNET_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 |