diff options
author | Nathan S. Evans <evans@in.tum.de> | 2010-03-19 12:43:34 +0000 |
---|---|---|
committer | Nathan S. Evans <evans@in.tum.de> | 2010-03-19 12:43:34 +0000 |
commit | 0c996c9a9e418c21c7e063d443f4fa1846b9448e (patch) | |
tree | adcecf9285343713af6dfd1bb37aaa138b27a8bc /src/dht/dht_api.c | |
parent | 9618f4481593c6300c04e8253f2e03a2380a899d (diff) | |
download | gnunet-0c996c9a9e418c21c7e063d443f4fa1846b9448e.tar.gz gnunet-0c996c9a9e418c21c7e063d443f4fa1846b9448e.zip |
added better continuation behavior to get start, put, and route start. test case now properly handles message confirmation receipts from service. find_peer api call still needs implemented, but we are generally much closer to a working point. i'm sure there are coverity issues as well as doxygen crap to be addressed
Diffstat (limited to 'src/dht/dht_api.c')
-rw-r--r-- | src/dht/dht_api.c | 81 |
1 files changed, 53 insertions, 28 deletions
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c index 2b105e621..a2a8a7bf3 100644 --- a/src/dht/dht_api.c +++ b/src/dht/dht_api.c | |||
@@ -64,7 +64,7 @@ struct PendingMessage | |||
64 | * Continuation to call on message send | 64 | * Continuation to call on message send |
65 | * or message receipt confirmation | 65 | * or message receipt confirmation |
66 | */ | 66 | */ |
67 | GNUNET_DHT_MessageCallback cont; | 67 | GNUNET_SCHEDULER_Task cont; |
68 | 68 | ||
69 | /** | 69 | /** |
70 | * Continuation closure | 70 | * Continuation closure |
@@ -269,7 +269,6 @@ void service_message_handler (void *cls, | |||
269 | return; | 269 | return; |
270 | } | 270 | } |
271 | 271 | ||
272 | |||
273 | if (ntohs(msg->type) == GNUNET_MESSAGE_TYPE_DHT) | 272 | if (ntohs(msg->type) == GNUNET_MESSAGE_TYPE_DHT) |
274 | { | 273 | { |
275 | dht_msg = (struct GNUNET_DHT_Message *)msg; | 274 | dht_msg = (struct GNUNET_DHT_Message *)msg; |
@@ -305,7 +304,7 @@ void service_message_handler (void *cls, | |||
305 | uid = GNUNET_ntohll(stop_msg->unique_id); | 304 | uid = GNUNET_ntohll(stop_msg->unique_id); |
306 | #if DEBUG_DHT_API | 305 | #if DEBUG_DHT_API |
307 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 306 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
308 | "`%s': Received response to message (uid %llu)\n", "DHT API", uid); | 307 | "`%s': Received response to message (uid %llu), current uid %llu\n", "DHT API", uid, handle->current->unique_id); |
309 | #endif | 308 | #endif |
310 | if (handle->current->unique_id == uid) | 309 | if (handle->current->unique_id == uid) |
311 | { | 310 | { |
@@ -314,12 +313,24 @@ void service_message_handler (void *cls, | |||
314 | "`%s': Have pending confirmation for this message!\n", "DHT API", uid); | 313 | "`%s': Have pending confirmation for this message!\n", "DHT API", uid); |
315 | #endif | 314 | #endif |
316 | if (handle->current->cont != NULL) | 315 | if (handle->current->cont != NULL) |
317 | handle->current->cont(handle->current->cont_cls, GNUNET_OK); | 316 | GNUNET_SCHEDULER_add_continuation(handle->sched, handle->current->cont, handle->current->cont_cls, GNUNET_SCHEDULER_REASON_PREREQ_DONE); |
317 | |||
318 | GNUNET_free(handle->current->msg); | 318 | GNUNET_free(handle->current->msg); |
319 | handle->current = NULL; | ||
320 | GNUNET_free(handle->current); | 319 | GNUNET_free(handle->current); |
320 | handle->current = NULL; | ||
321 | } | 321 | } |
322 | } | 322 | } |
323 | else | ||
324 | { | ||
325 | #if DEBUG_DHT_API | ||
326 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
327 | "`%s': Received unknown message type %d\n", "DHT API", ntohs(msg->type)); | ||
328 | #endif | ||
329 | } | ||
330 | |||
331 | GNUNET_CLIENT_receive (handle->client, | ||
332 | &service_message_handler, | ||
333 | handle, GNUNET_TIME_UNIT_FOREVER_REL); | ||
323 | 334 | ||
324 | } | 335 | } |
325 | 336 | ||
@@ -416,7 +427,12 @@ finish (struct GNUNET_DHT_Handle *handle, int code) | |||
416 | if (pos->is_unique) | 427 | if (pos->is_unique) |
417 | { | 428 | { |
418 | if (pos->cont != NULL) | 429 | if (pos->cont != NULL) |
419 | pos->cont(pos->cont_cls, code); | 430 | { |
431 | if (code == GNUNET_SYSERR) | ||
432 | GNUNET_SCHEDULER_add_continuation(handle->sched, pos->cont, pos->cont_cls, GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
433 | else | ||
434 | GNUNET_SCHEDULER_add_continuation(handle->sched, pos->cont, pos->cont_cls, GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
435 | } | ||
420 | 436 | ||
421 | GNUNET_free(pos->msg); | 437 | GNUNET_free(pos->msg); |
422 | handle->current = NULL; | 438 | handle->current = NULL; |
@@ -480,12 +496,12 @@ transmit_pending (void *cls, size_t size, void *buf) | |||
480 | * @return GNUNET_YES on success, GNUNET_NO on failure. | 496 | * @return GNUNET_YES on success, GNUNET_NO on failure. |
481 | */ | 497 | */ |
482 | static int | 498 | static int |
483 | try_connect (struct GNUNET_DHT_Handle *ret) | 499 | try_connect (struct GNUNET_DHT_Handle *handle) |
484 | { | 500 | { |
485 | if (ret->client != NULL) | 501 | if (handle->client != NULL) |
486 | return GNUNET_OK; | 502 | return GNUNET_OK; |
487 | ret->client = GNUNET_CLIENT_connect (ret->sched, "dht", ret->cfg); | 503 | handle->client = GNUNET_CLIENT_connect (handle->sched, "dht", handle->cfg); |
488 | if (ret->client != NULL) | 504 | if (handle->client != NULL) |
489 | return GNUNET_YES; | 505 | return GNUNET_YES; |
490 | #if DEBUG_STATISTICS | 506 | #if DEBUG_STATISTICS |
491 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 507 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -574,7 +590,7 @@ GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle, | |||
574 | struct GNUNET_TIME_Relative timeout, | 590 | struct GNUNET_TIME_Relative timeout, |
575 | GNUNET_DHT_ReplyProcessor iter, | 591 | GNUNET_DHT_ReplyProcessor iter, |
576 | void *iter_cls, | 592 | void *iter_cls, |
577 | GNUNET_DHT_MessageCallback cont, | 593 | GNUNET_SCHEDULER_Task cont, |
578 | void *cont_cls) | 594 | void *cont_cls) |
579 | { | 595 | { |
580 | struct GNUNET_DHT_RouteHandle *route_handle; | 596 | struct GNUNET_DHT_RouteHandle *route_handle; |
@@ -583,15 +599,21 @@ GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle, | |||
583 | size_t is_unique; | 599 | size_t is_unique; |
584 | size_t msize; | 600 | size_t msize; |
585 | GNUNET_HashCode *uid_key; | 601 | GNUNET_HashCode *uid_key; |
586 | int count; | ||
587 | uint64_t uid; | 602 | uint64_t uid; |
588 | 603 | ||
589 | uid = 0; | ||
590 | is_unique = GNUNET_YES; | 604 | is_unique = GNUNET_YES; |
591 | if (iter == NULL) | 605 | if (iter == NULL) |
592 | is_unique = GNUNET_NO; | 606 | is_unique = GNUNET_NO; |
593 | 607 | ||
594 | route_handle = NULL; | 608 | route_handle = NULL; |
609 | uid_key = NULL; | ||
610 | |||
611 | do | ||
612 | { | ||
613 | GNUNET_free_non_null(uid_key); | ||
614 | uid = GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_WEAK, -1); | ||
615 | uid_key = hash_from_uid(uid); | ||
616 | } while (GNUNET_CONTAINER_multihashmap_contains(handle->outstanding_requests, uid_key) == GNUNET_YES); | ||
595 | 617 | ||
596 | if (is_unique) | 618 | if (is_unique) |
597 | { | 619 | { |
@@ -600,32 +622,24 @@ GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle, | |||
600 | route_handle->iter = iter; | 622 | route_handle->iter = iter; |
601 | route_handle->iter_cls = iter_cls; | 623 | route_handle->iter_cls = iter_cls; |
602 | route_handle->dht_handle = handle; | 624 | route_handle->dht_handle = handle; |
603 | route_handle->uid = GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_WEAK, -1); | 625 | route_handle->uid = uid; |
604 | uid = route_handle->uid; | ||
605 | #if DEBUG_DHT_API | 626 | #if DEBUG_DHT_API |
606 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 627 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
607 | "`%s': Unique ID is %llu\n", "DHT API", uid); | 628 | "`%s': Unique ID is %llu\n", "DHT API", uid); |
608 | #endif | 629 | #endif |
609 | count = 0; | ||
610 | uid_key = hash_from_uid(route_handle->uid); | ||
611 | /* While we have an outstanding request with the same identifier! */ | ||
612 | while (GNUNET_CONTAINER_multihashmap_contains(handle->outstanding_requests, uid_key) == GNUNET_YES) | ||
613 | { | ||
614 | GNUNET_free(uid_key); | ||
615 | uid_key = hash_from_uid(route_handle->uid); | ||
616 | } | ||
617 | /** | 630 | /** |
618 | * Store based on random identifier! | 631 | * Store based on random identifier! |
619 | */ | 632 | */ |
620 | GNUNET_CONTAINER_multihashmap_put(handle->outstanding_requests, uid_key, route_handle, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 633 | GNUNET_CONTAINER_multihashmap_put(handle->outstanding_requests, uid_key, route_handle, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
621 | msize = sizeof(struct GNUNET_DHT_Message) + ntohs(enc->size); | 634 | msize = sizeof(struct GNUNET_DHT_Message) + ntohs(enc->size); |
622 | GNUNET_free(uid_key); | 635 | |
623 | } | 636 | } |
624 | else | 637 | else |
625 | { | 638 | { |
626 | msize = sizeof(struct GNUNET_DHT_Message) + ntohs(enc->size); | 639 | msize = sizeof(struct GNUNET_DHT_Message) + ntohs(enc->size); |
627 | } | 640 | } |
628 | 641 | ||
642 | GNUNET_free(uid_key); | ||
629 | message = GNUNET_malloc(msize); | 643 | message = GNUNET_malloc(msize); |
630 | message->header.size = htons(msize); | 644 | message->header.size = htons(msize); |
631 | message->header.type = htons(GNUNET_MESSAGE_TYPE_DHT); | 645 | message->header.type = htons(GNUNET_MESSAGE_TYPE_DHT); |
@@ -642,6 +656,7 @@ GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle, | |||
642 | pending->cont = cont; | 656 | pending->cont = cont; |
643 | pending->cont_cls = cont_cls; | 657 | pending->cont_cls = cont_cls; |
644 | pending->is_unique = is_unique; | 658 | pending->is_unique = is_unique; |
659 | pending->unique_id = uid; | ||
645 | 660 | ||
646 | GNUNET_assert(handle->current == NULL); | 661 | GNUNET_assert(handle->current == NULL); |
647 | 662 | ||
@@ -670,6 +685,9 @@ void dht_get_processor (void *cls, | |||
670 | * @param key the key to look up | 685 | * @param key the key to look up |
671 | * @param iter function to call on each result | 686 | * @param iter function to call on each result |
672 | * @param iter_cls closure for iter | 687 | * @param iter_cls closure for iter |
688 | * @param cont continuation to call once message sent | ||
689 | * @param cont_cls closure for continuation | ||
690 | * | ||
673 | * @return handle to stop the async get | 691 | * @return handle to stop the async get |
674 | */ | 692 | */ |
675 | struct GNUNET_DHT_RouteHandle * | 693 | struct GNUNET_DHT_RouteHandle * |
@@ -678,7 +696,9 @@ GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle, | |||
678 | uint32_t type, | 696 | uint32_t type, |
679 | const GNUNET_HashCode * key, | 697 | const GNUNET_HashCode * key, |
680 | GNUNET_DHT_GetIterator iter, | 698 | GNUNET_DHT_GetIterator iter, |
681 | void *iter_cls) | 699 | void *iter_cls, |
700 | GNUNET_SCHEDULER_Task cont, | ||
701 | void *cont_cls) | ||
682 | { | 702 | { |
683 | struct GNUNET_DHT_GetContext *get_context; | 703 | struct GNUNET_DHT_GetContext *get_context; |
684 | struct GNUNET_DHT_GetMessage *get_msg; | 704 | struct GNUNET_DHT_GetMessage *get_msg; |
@@ -700,7 +720,7 @@ GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle, | |||
700 | get_msg->header.size = htons(sizeof(struct GNUNET_DHT_GetMessage)); | 720 | get_msg->header.size = htons(sizeof(struct GNUNET_DHT_GetMessage)); |
701 | get_msg->type = htonl(type); | 721 | get_msg->type = htonl(type); |
702 | 722 | ||
703 | return GNUNET_DHT_route_start(handle, key, 0, 0, &get_msg->header, timeout, &get_reply_iterator, get_context, NULL, NULL); | 723 | return GNUNET_DHT_route_start(handle, key, 0, 0, &get_msg->header, timeout, &get_reply_iterator, get_context, cont, cont_cls); |
704 | 724 | ||
705 | } | 725 | } |
706 | 726 | ||
@@ -724,12 +744,15 @@ GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle) | |||
724 | #endif | 744 | #endif |
725 | message->unique_id = GNUNET_htonll(route_handle->uid); | 745 | message->unique_id = GNUNET_htonll(route_handle->uid); |
726 | 746 | ||
747 | GNUNET_assert(route_handle->dht_handle->current == NULL); | ||
748 | |||
727 | pending = GNUNET_malloc(sizeof(struct PendingMessage)); | 749 | pending = GNUNET_malloc(sizeof(struct PendingMessage)); |
728 | pending->msg = (struct GNUNET_MessageHeader *)message; | 750 | pending->msg = (struct GNUNET_MessageHeader *)message; |
729 | pending->timeout = DEFAULT_DHT_TIMEOUT; | 751 | pending->timeout = DEFAULT_DHT_TIMEOUT; |
730 | pending->cont = NULL; | 752 | pending->cont = NULL; |
731 | pending->cont_cls = NULL; | 753 | pending->cont_cls = NULL; |
732 | pending->is_unique = GNUNET_NO; | 754 | pending->is_unique = GNUNET_NO; |
755 | pending->unique_id = route_handle->uid; | ||
733 | 756 | ||
734 | GNUNET_assert(route_handle->dht_handle->current == NULL); | 757 | GNUNET_assert(route_handle->dht_handle->current == NULL); |
735 | 758 | ||
@@ -811,7 +834,7 @@ GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, | |||
811 | const char *data, | 834 | const char *data, |
812 | struct GNUNET_TIME_Absolute exp, | 835 | struct GNUNET_TIME_Absolute exp, |
813 | struct GNUNET_TIME_Relative timeout, | 836 | struct GNUNET_TIME_Relative timeout, |
814 | GNUNET_DHT_MessageCallback cont, | 837 | GNUNET_SCHEDULER_Task cont, |
815 | void *cont_cls) | 838 | void *cont_cls) |
816 | { | 839 | { |
817 | struct GNUNET_DHT_PutMessage *put_msg; | 840 | struct GNUNET_DHT_PutMessage *put_msg; |
@@ -819,7 +842,7 @@ GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, | |||
819 | 842 | ||
820 | if (handle->current != NULL) | 843 | if (handle->current != NULL) |
821 | { | 844 | { |
822 | cont(cont_cls, GNUNET_SYSERR); | 845 | GNUNET_SCHEDULER_add_continuation(handle->sched, cont, cont_cls, GNUNET_SCHEDULER_REASON_TIMEOUT); |
823 | return; | 846 | return; |
824 | } | 847 | } |
825 | 848 | ||
@@ -833,6 +856,8 @@ GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, | |||
833 | put_msg->header.type = htons(GNUNET_MESSAGE_TYPE_DHT_PUT); | 856 | put_msg->header.type = htons(GNUNET_MESSAGE_TYPE_DHT_PUT); |
834 | put_msg->header.size = htons(msize); | 857 | put_msg->header.size = htons(msize); |
835 | put_msg->type = htonl(type); | 858 | put_msg->type = htonl(type); |
859 | put_msg->data_size = htons(size); | ||
860 | put_msg->expiration = exp; | ||
836 | memcpy(&put_msg[1], data, size); | 861 | memcpy(&put_msg[1], data, size); |
837 | 862 | ||
838 | GNUNET_DHT_route_start(handle, key, 0, 0, &put_msg->header, timeout, NULL, NULL, cont, cont_cls); | 863 | GNUNET_DHT_route_start(handle, key, 0, 0, &put_msg->header, timeout, NULL, NULL, cont, cont_cls); |