aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht.c
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-09-14 13:54:46 +0000
committerBart Polot <bart@net.in.tum.de>2011-09-14 13:54:46 +0000
commit89116db69e4e81337ddbd3c03e2bd50fe2bb8eab (patch)
tree3d8ef873fcf2d7b16ab62aca3d0edfc35cfda123 /src/dht/gnunet-service-dht.c
parent58e48024d5348b32ef9ca7ef91734c4852d20edc (diff)
downloadgnunet-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.c101
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",