diff options
author | Bart Polot <bart@net.in.tum.de> | 2011-09-14 13:54:46 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2011-09-14 13:54:46 +0000 |
commit | 89116db69e4e81337ddbd3c03e2bd50fe2bb8eab (patch) | |
tree | 3d8ef873fcf2d7b16ab62aca3d0edfc35cfda123 /src/dht/gnunet-service-dht.c | |
parent | 58e48024d5348b32ef9ca7ef91734c4852d20edc (diff) | |
download | gnunet-89116db69e4e81337ddbd3c03e2bd50fe2bb8eab.tar.gz gnunet-89116db69e4e81337ddbd3c03e2bd50fe2bb8eab.zip |
Added code for handling a case when a PUT is received with a key for which there is an active GET query.
Diffstat (limited to 'src/dht/gnunet-service-dht.c')
-rw-r--r-- | src/dht/gnunet-service-dht.c | 101 |
1 files changed, 82 insertions, 19 deletions
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c index a68ba5563..838744d9e 100644 --- a/src/dht/gnunet-service-dht.c +++ b/src/dht/gnunet-service-dht.c | |||
@@ -479,6 +479,11 @@ struct DHTRouteSource | |||
479 | struct DHTRouteSource *prev; | 479 | struct DHTRouteSource *prev; |
480 | 480 | ||
481 | /** | 481 | /** |
482 | * UID of the request | ||
483 | */ | ||
484 | uint64_t uid; | ||
485 | |||
486 | /** | ||
482 | * Source of the request. Replies should be forwarded to | 487 | * Source of the request. Replies should be forwarded to |
483 | * this peer. | 488 | * this peer. |
484 | */ | 489 | */ |
@@ -2243,7 +2248,7 @@ handle_dht_get (const struct GNUNET_MessageHeader *msg, | |||
2243 | if (msize != | 2248 | if (msize != |
2244 | sizeof (struct GNUNET_DHT_GetMessage) + bf_size + msg_ctx->xquery_size) | 2249 | sizeof (struct GNUNET_DHT_GetMessage) + bf_size + msg_ctx->xquery_size) |
2245 | { | 2250 | { |
2246 | GNUNET_break (0); | 2251 | GNUNET_break_op (0); |
2247 | return 0; | 2252 | return 0; |
2248 | } | 2253 | } |
2249 | end = (const char *) &get_msg[1]; | 2254 | end = (const char *) &get_msg[1]; |
@@ -2656,37 +2661,94 @@ handle_dht_put (const struct GNUNET_MessageHeader *msg, | |||
2656 | } | 2661 | } |
2657 | #endif | 2662 | #endif |
2658 | 2663 | ||
2659 | // GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "******************************************************** PUT 1\n"); | 2664 | record = GNUNET_CONTAINER_multihashmap_get(forward_list.hashmap, |
2660 | record = | 2665 | &msg_ctx->key); |
2661 | GNUNET_CONTAINER_multihashmap_get (forward_list.hashmap, &msg_ctx->key); | ||
2662 | if (NULL != record) | 2666 | if (NULL != record) |
2663 | { | 2667 | { |
2664 | struct DHTRouteSource *pos; | 2668 | struct DHTRouteSource *pos; |
2665 | struct GNUNET_DHT_GetMessage *gmsg; | 2669 | struct GNUNET_DHT_GetResultMessage *get_result; |
2666 | size_t gsize; | 2670 | struct DHT_MessageContext *new_msg_ctx; |
2671 | size_t get_size; | ||
2667 | 2672 | ||
2668 | // GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "******************************************************** PUT 2\n"); | ||
2669 | pos = record->head; | 2673 | pos = record->head; |
2670 | while (pos != NULL) | 2674 | while (pos != NULL) |
2671 | { | 2675 | { |
2672 | /* TODO: do only for local started requests? or also for remote peers? */ | 2676 | /* TODO: do only for local started requests? or also for remote peers? */ |
2673 | /* TODO: include this in statistics? under what? */ | 2677 | /* TODO: include this in statistics? under what? */ |
2678 | /* TODO: reverse order of path_history? */ | ||
2674 | if (NULL == pos->client) | 2679 | if (NULL == pos->client) |
2680 | { | ||
2681 | pos = pos->next; | ||
2675 | continue; | 2682 | continue; |
2683 | } | ||
2676 | 2684 | ||
2677 | gsize = data_size + sizeof (struct GNUNET_DHT_GetMessage); | 2685 | /********** CODE ADAPTED FROM DATACHACHE_GET_ITERATOR BEGIN *************/ |
2678 | gmsg = GNUNET_malloc (gsize); | 2686 | new_msg_ctx = GNUNET_malloc (sizeof (struct DHT_MessageContext)); |
2679 | gmsg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_GET_RESULT); | 2687 | memcpy (new_msg_ctx, msg_ctx, sizeof (struct DHT_MessageContext)); |
2680 | gmsg->header.size = htons (gsize); | 2688 | if (GNUNET_DHT_RO_RECORD_ROUTE == |
2681 | gmsg->type = put_msg->type; | 2689 | (msg_ctx->msg_options & GNUNET_DHT_RO_RECORD_ROUTE)) |
2682 | memcpy (&gmsg[1], &put_msg[1], data_size); | 2690 | { |
2691 | new_msg_ctx->msg_options = GNUNET_DHT_RO_RECORD_ROUTE; | ||
2692 | new_msg_ctx->path_history_len = msg_ctx->path_history_len; | ||
2693 | /* Assign to previous msg_ctx path history, caller should free after our return */ | ||
2694 | new_msg_ctx->path_history = msg_ctx->path_history; | ||
2695 | #if DEBUG_PATH | ||
2696 | for (i = 0; i < new_msg_ctx->path_history_len; i++) | ||
2697 | { | ||
2698 | path_offset = | ||
2699 | &new_msg_ctx->path_history[i * sizeof (struct GNUNET_PeerIdentity)]; | ||
2700 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2701 | "(put for active get) Key %s Found peer %d:%s\n", | ||
2702 | GNUNET_h2s (&msg_ctx->key), i, | ||
2703 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) path_offset)); | ||
2704 | } | ||
2705 | #endif | ||
2706 | } | ||
2683 | 2707 | ||
2684 | /* TODO: duplicate and reverse order of path_history? */ | 2708 | get_size = |
2685 | send_reply_to_client (pos->client, &gmsg->header, msg_ctx); | 2709 | sizeof (struct GNUNET_DHT_GetResultMessage) + data_size + |
2686 | GNUNET_free (gmsg); | 2710 | (msg_ctx->path_history_len * sizeof (struct GNUNET_PeerIdentity)); |
2711 | get_result = GNUNET_malloc (get_size); | ||
2712 | get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_GET_RESULT); | ||
2713 | get_result->header.size = htons (get_size); | ||
2714 | get_result->expiration = put_msg->expiration; | ||
2715 | get_result->type = put_msg->type; | ||
2716 | get_result->put_path_length = htons (msg_ctx->path_history_len); | ||
2717 | #if DEBUG_PATH | ||
2718 | path_offset = msg_ctx->path_history; | ||
2719 | for (i = 0; i < msg_ctx->path_history_len; i++) | ||
2720 | { | ||
2721 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2722 | "(get_iterator PUT path) Key %s Found peer %d:%s\n", | ||
2723 | GNUNET_h2s (&msg_ctx->key), i, | ||
2724 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) | ||
2725 | &path_offset[i * | ||
2726 | sizeof (struct | ||
2727 | GNUNET_PeerIdentity)])); | ||
2728 | } | ||
2729 | #endif | ||
2730 | /* Copy the actual data and the path_history to the end of the get result */ | ||
2731 | memcpy (&get_result[1], &put_msg[1], data_size); | ||
2732 | path_offset = (char *) &get_result[1]; | ||
2733 | path_offset += data_size; | ||
2734 | memcpy (path_offset, msg_ctx->path_history, | ||
2735 | msg_ctx->path_history_len * sizeof (struct GNUNET_PeerIdentity)); | ||
2736 | new_msg_ctx->peer = &my_identity; | ||
2737 | new_msg_ctx->bloom = | ||
2738 | GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K); | ||
2739 | new_msg_ctx->hop_count = 0; | ||
2740 | /* Make result routing a higher priority */ | ||
2741 | new_msg_ctx->importance = DHT_DEFAULT_P2P_IMPORTANCE + 2; | ||
2742 | new_msg_ctx->timeout = DHT_DEFAULT_P2P_TIMEOUT; | ||
2743 | new_msg_ctx->unique_id = pos->uid; | ||
2744 | send_reply_to_client(pos->client, &get_result->header, new_msg_ctx); | ||
2745 | // GNUNET_CONTAINER_bloomfilter_free (new_msg_ctx->bloom); | ||
2746 | GNUNET_free (new_msg_ctx); | ||
2747 | GNUNET_free (get_result); | ||
2748 | /********** CODE ADAPTED FROM DATACHACHE_GET_ITERATOR END ***************/ | ||
2749 | pos = pos->next; | ||
2687 | } | 2750 | } |
2688 | } | 2751 | } |
2689 | // GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "******************************************************** PUT END\n"); | ||
2690 | 2752 | ||
2691 | if (msg_ctx->closest != GNUNET_YES) | 2753 | if (msg_ctx->closest != GNUNET_YES) |
2692 | { | 2754 | { |
@@ -3133,8 +3195,8 @@ cache_response (struct DHT_MessageContext *msg_ctx) | |||
3133 | source_info); | 3195 | source_info); |
3134 | source_info->find_peers_responded = | 3196 | source_info->find_peers_responded = |
3135 | GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K); | 3197 | GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K); |
3136 | memcpy (&source_info->source, msg_ctx->peer, | 3198 | /* FIXME bart assign instead of memcpy (more explicit) */ |
3137 | sizeof (struct GNUNET_PeerIdentity)); | 3199 | source_info->source = *msg_ctx->peer; |
3138 | GNUNET_CONTAINER_DLL_insert_after (record->head, record->tail, record->tail, | 3200 | GNUNET_CONTAINER_DLL_insert_after (record->head, record->tail, record->tail, |
3139 | source_info); | 3201 | source_info); |
3140 | if (msg_ctx->client != NULL) /* For local request, set timeout so high it effectively never gets pushed out */ | 3202 | if (msg_ctx->client != NULL) /* For local request, set timeout so high it effectively never gets pushed out */ |
@@ -3145,6 +3207,7 @@ cache_response (struct DHT_MessageContext *msg_ctx) | |||
3145 | source_info->hnode = | 3207 | source_info->hnode = |
3146 | GNUNET_CONTAINER_heap_insert (forward_list.minHeap, source_info, | 3208 | GNUNET_CONTAINER_heap_insert (forward_list.minHeap, source_info, |
3147 | now.abs_value); | 3209 | now.abs_value); |
3210 | source_info->uid = msg_ctx->unique_id; | ||
3148 | #if DEBUG_DHT > 1 | 3211 | #if DEBUG_DHT > 1 |
3149 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3212 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3150 | "`%s:%s': Created new forward source info for %s uid %llu\n", | 3213 | "`%s:%s': Created new forward source info for %s uid %llu\n", |