aboutsummaryrefslogtreecommitdiff
path: root/src/dht/dht_api.c
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2010-03-19 12:43:34 +0000
committerNathan S. Evans <evans@in.tum.de>2010-03-19 12:43:34 +0000
commit0c996c9a9e418c21c7e063d443f4fa1846b9448e (patch)
treeadcecf9285343713af6dfd1bb37aaa138b27a8bc /src/dht/dht_api.c
parent9618f4481593c6300c04e8253f2e03a2380a899d (diff)
downloadgnunet-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.c81
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 */
482static int 498static int
483try_connect (struct GNUNET_DHT_Handle *ret) 499try_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 */
675struct GNUNET_DHT_RouteHandle * 693struct 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);