aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dht/dht.h29
-rw-r--r--src/dht/gnunet-service-dht.c94
2 files changed, 100 insertions, 23 deletions
diff --git a/src/dht/dht.h b/src/dht/dht.h
index 094cfb7d8..4e8782bb5 100644
--- a/src/dht/dht.h
+++ b/src/dht/dht.h
@@ -267,6 +267,13 @@ struct GNUNET_DHT_P2PRouteMessage
267 uint32_t network_size GNUNET_PACKED; 267 uint32_t network_size GNUNET_PACKED;
268 268
269 /** 269 /**
270 * Route path length; number of GNUNET_PeerIdentity's
271 * copied to the end of this message (before the actual
272 * encapsulated message)
273 */
274 uint32_t route_path_length GNUNET_PACKED;
275
276 /**
270 * Unique ID identifying this request 277 * Unique ID identifying this request
271 */ 278 */
272 uint64_t unique_id GNUNET_PACKED; 279 uint64_t unique_id GNUNET_PACKED;
@@ -287,13 +294,6 @@ struct GNUNET_DHT_P2PRouteMessage
287 294
288/** 295/**
289 * Generic P2P route result 296 * Generic P2P route result
290 *
291 * FIXME: One question is how much to include for a route result message.
292 * Assuming a peer receives such a message, but has no record of a
293 * route message, what should it do? It can either drop the message
294 * or try to forward it towards the original peer... However, for
295 * that to work we would need to include the original peer identity
296 * in the GET request, which adds more data to the message.
297 */ 297 */
298struct GNUNET_DHT_P2PRouteResultMessage 298struct GNUNET_DHT_P2PRouteResultMessage
299{ 299{
@@ -303,18 +303,11 @@ struct GNUNET_DHT_P2PRouteResultMessage
303 struct GNUNET_MessageHeader header; 303 struct GNUNET_MessageHeader header;
304 304
305 /** 305 /**
306 * Number of peers recorded in the "PUT" path. 306 * Number of peers recorded in the path
307 * (original path message took during "PUT"). These 307 * (inverse of the path the outgoing message took).
308 * peer identities follow this message. 308 * These peer identities follow this message.
309 */
310 uint16_t put_path_length GNUNET_PACKED;
311
312 /**
313 * Number of peers recorded in the "GET" path
314 * (inverse of the path the GET message took). These
315 * peer identities follow this message.
316 */ 309 */
317 uint16_t get_path_length GNUNET_PACKED; 310 uint16_t outgoing_path_length GNUNET_PACKED;
318 311
319 /** 312 /**
320 * Message options 313 * Message options
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c
index c4d3e136e..b8f7e4732 100644
--- a/src/dht/gnunet-service-dht.c
+++ b/src/dht/gnunet-service-dht.c
@@ -482,6 +482,16 @@ struct DHT_MessageContext
482 uint32_t hop_count; 482 uint32_t hop_count;
483 483
484 /** 484 /**
485 * How many peer identities are present in the path history?
486 */
487 uint32_t path_history_len;
488
489 /**
490 * Path history.
491 */
492 char *path_history;
493
494 /**
485 * How important is this message? 495 * How important is this message?
486 */ 496 */
487 unsigned int importance; 497 unsigned int importance;
@@ -1085,10 +1095,11 @@ forward_result_message (const struct GNUNET_MessageHeader *msg,
1085 struct P2PPendingMessage *pending; 1095 struct P2PPendingMessage *pending;
1086 size_t msize; 1096 size_t msize;
1087 size_t psize; 1097 size_t psize;
1098 char *path_start;
1088 1099
1089 increment_stats (STAT_RESULT_FORWARDS); 1100 increment_stats (STAT_RESULT_FORWARDS);
1090 msize = 1101 msize =
1091 sizeof (struct GNUNET_DHT_P2PRouteResultMessage) + ntohs (msg->size); 1102 sizeof (struct GNUNET_DHT_P2PRouteResultMessage) + ntohs (msg->size) + (sizeof(struct GNUNET_PeerIdentity) * msg_ctx->path_history_len);
1092 GNUNET_assert (msize <= GNUNET_SERVER_MAX_MESSAGE_SIZE); 1103 GNUNET_assert (msize <= GNUNET_SERVER_MAX_MESSAGE_SIZE);
1093 psize = sizeof (struct P2PPendingMessage) + msize; 1104 psize = sizeof (struct P2PPendingMessage) + msize;
1094 pending = GNUNET_malloc (psize); 1105 pending = GNUNET_malloc (psize);
@@ -1099,8 +1110,15 @@ forward_result_message (const struct GNUNET_MessageHeader *msg,
1099 result_message->header.size = htons (msize); 1110 result_message->header.size = htons (msize);
1100 result_message->header.type = 1111 result_message->header.type =
1101 htons (GNUNET_MESSAGE_TYPE_DHT_P2P_ROUTE_RESULT); 1112 htons (GNUNET_MESSAGE_TYPE_DHT_P2P_ROUTE_RESULT);
1102 result_message->put_path_length = htons (0); /* FIXME: implement */ 1113 result_message->outgoing_path_length = htonl (msg_ctx->path_history_len);
1103 result_message->get_path_length = htons (0); /* FIXME: implement */ 1114 if (msg_ctx->path_history_len > 0)
1115 {
1116 /* End of pending is where enc_msg starts */
1117 path_start = (char *)&pending[1];
1118 /* Offset by the size of the enc_msg */
1119 path_start += ntohs (msg->size);
1120 memcpy(path_start, msg_ctx->path_history, msg_ctx->path_history_len * (sizeof(struct GNUNET_PeerIdentity)));
1121 }
1104 result_message->options = htonl (msg_ctx->msg_options); 1122 result_message->options = htonl (msg_ctx->msg_options);
1105 result_message->hop_count = htonl (msg_ctx->hop_count + 1); 1123 result_message->hop_count = htonl (msg_ctx->hop_count + 1);
1106 GNUNET_assert (GNUNET_OK == 1124 GNUNET_assert (GNUNET_OK ==
@@ -1723,6 +1741,7 @@ forward_message (const struct GNUNET_MessageHeader *msg,
1723 struct P2PPendingMessage *pending; 1741 struct P2PPendingMessage *pending;
1724 size_t msize; 1742 size_t msize;
1725 size_t psize; 1743 size_t psize;
1744 char *route_path;
1726 1745
1727 increment_stats (STAT_ROUTE_FORWARDS); 1746 increment_stats (STAT_ROUTE_FORWARDS);
1728 GNUNET_assert (peer != NULL); 1747 GNUNET_assert (peer != NULL);
@@ -1730,7 +1749,7 @@ forward_message (const struct GNUNET_MessageHeader *msg,
1730 && (peer == find_closest_peer (&msg_ctx->key))) 1749 && (peer == find_closest_peer (&msg_ctx->key)))
1731 increment_stats (STAT_ROUTE_FORWARDS_CLOSEST); 1750 increment_stats (STAT_ROUTE_FORWARDS_CLOSEST);
1732 1751
1733 msize = sizeof (struct GNUNET_DHT_P2PRouteMessage) + ntohs (msg->size); 1752 msize = sizeof (struct GNUNET_DHT_P2PRouteMessage) + ntohs (msg->size) + (msg_ctx->path_history_len * sizeof(struct GNUNET_PeerIdentity));
1734 GNUNET_assert (msize <= GNUNET_SERVER_MAX_MESSAGE_SIZE); 1753 GNUNET_assert (msize <= GNUNET_SERVER_MAX_MESSAGE_SIZE);
1735 psize = sizeof (struct P2PPendingMessage) + msize; 1754 psize = sizeof (struct P2PPendingMessage) + msize;
1736 pending = GNUNET_malloc (psize); 1755 pending = GNUNET_malloc (psize);
@@ -1753,6 +1772,16 @@ forward_message (const struct GNUNET_MessageHeader *msg,
1753 DHT_BLOOM_SIZE)); 1772 DHT_BLOOM_SIZE));
1754 memcpy (&route_message->key, &msg_ctx->key, sizeof (GNUNET_HashCode)); 1773 memcpy (&route_message->key, &msg_ctx->key, sizeof (GNUNET_HashCode));
1755 memcpy (&route_message[1], msg, ntohs (msg->size)); 1774 memcpy (&route_message[1], msg, ntohs (msg->size));
1775 if (GNUNET_DHT_RO_RECORD_ROUTE == (msg_ctx->msg_options & GNUNET_DHT_RO_RECORD_ROUTE))
1776 {
1777 route_message->route_path_length = htonl(msg_ctx->path_history_len);
1778 /* Set pointer to start of enc_msg */
1779 route_path = (char *)&route_message[1];
1780 /* Offset to the end of the enc_msg */
1781 route_path += ntohs (msg->size);
1782 /* Copy the route_path after enc_msg */
1783 memcpy (route_path, msg_ctx->path_history, msg_ctx->path_history_len * sizeof(struct GNUNET_PeerIdentity));
1784 }
1756#if DEBUG_DHT > 1 1785#if DEBUG_DHT > 1
1757 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1786 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1758 "%s:%s Adding pending message size %d for peer %s\n", 1787 "%s:%s Adding pending message size %d for peer %s\n",
@@ -2304,6 +2333,13 @@ datacache_get_iterator (void *cls,
2304 case GNUNET_BLOCK_EVALUATION_OK_MORE: 2333 case GNUNET_BLOCK_EVALUATION_OK_MORE:
2305 new_msg_ctx = GNUNET_malloc (sizeof (struct DHT_MessageContext)); 2334 new_msg_ctx = GNUNET_malloc (sizeof (struct DHT_MessageContext));
2306 memcpy (new_msg_ctx, msg_ctx, sizeof (struct DHT_MessageContext)); 2335 memcpy (new_msg_ctx, msg_ctx, sizeof (struct DHT_MessageContext));
2336 if (GNUNET_DHT_RO_RECORD_ROUTE == (msg_ctx->msg_options & GNUNET_DHT_RO_RECORD_ROUTE))
2337 {
2338 new_msg_ctx->msg_options = GNUNET_DHT_RO_RECORD_ROUTE;
2339 new_msg_ctx->path_history_len = msg_ctx->path_history_len;
2340 /* Assign to previous msg_ctx path history, caller should free after our return */
2341 new_msg_ctx->path_history = msg_ctx->path_history;
2342 }
2307 get_result = 2343 get_result =
2308 GNUNET_malloc (sizeof (struct GNUNET_DHT_GetResultMessage) + size); 2344 GNUNET_malloc (sizeof (struct GNUNET_DHT_GetResultMessage) + size);
2309 get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_GET_RESULT); 2345 get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_GET_RESULT);
@@ -2702,6 +2738,13 @@ handle_dht_find_peer (const struct GNUNET_MessageHeader *find_msg,
2702 new_msg_ctx->importance = DHT_DEFAULT_P2P_IMPORTANCE + 2; /* Make find peer requests a higher priority */ 2738 new_msg_ctx->importance = DHT_DEFAULT_P2P_IMPORTANCE + 2; /* Make find peer requests a higher priority */
2703 new_msg_ctx->timeout = DHT_DEFAULT_P2P_TIMEOUT; 2739 new_msg_ctx->timeout = DHT_DEFAULT_P2P_TIMEOUT;
2704 increment_stats (STAT_FIND_PEER_ANSWER); 2740 increment_stats (STAT_FIND_PEER_ANSWER);
2741 if (GNUNET_DHT_RO_RECORD_ROUTE == (msg_ctx->msg_options & GNUNET_DHT_RO_RECORD_ROUTE))
2742 {
2743 new_msg_ctx->msg_options = GNUNET_DHT_RO_RECORD_ROUTE;
2744 new_msg_ctx->path_history_len = msg_ctx->path_history_len;
2745 /* Assign to previous msg_ctx path history, caller should free after our return */
2746 new_msg_ctx->path_history = msg_ctx->path_history;
2747 }
2705 route_result_message (find_peer_result, new_msg_ctx); 2748 route_result_message (find_peer_result, new_msg_ctx);
2706 GNUNET_free (new_msg_ctx); 2749 GNUNET_free (new_msg_ctx);
2707#if DEBUG_DHT_ROUTING 2750#if DEBUG_DHT_ROUTING
@@ -3914,6 +3957,7 @@ demultiplex_message (const struct GNUNET_MessageHeader *msg,
3914{ 3957{
3915 /* FIXME: Should we use closest excluding those we won't route to (the bloomfilter problem)? */ 3958 /* FIXME: Should we use closest excluding those we won't route to (the bloomfilter problem)? */
3916 msg_ctx->closest = am_closest_peer (&msg_ctx->key, msg_ctx->bloom); 3959 msg_ctx->closest = am_closest_peer (&msg_ctx->key, msg_ctx->bloom);
3960
3917 switch (ntohs (msg->type)) 3961 switch (ntohs (msg->type))
3918 { 3962 {
3919 case GNUNET_MESSAGE_TYPE_DHT_GET: /* Add to hashmap of requests seen, search for data (always) */ 3963 case GNUNET_MESSAGE_TYPE_DHT_GET: /* Add to hashmap of requests seen, search for data (always) */
@@ -4462,6 +4506,12 @@ handle_dht_local_route_request (void *cls,
4462 msg_ctx.unique_id = GNUNET_ntohll (dht_msg->unique_id); 4506 msg_ctx.unique_id = GNUNET_ntohll (dht_msg->unique_id);
4463 msg_ctx.replication = ntohl (dht_msg->desired_replication_level); 4507 msg_ctx.replication = ntohl (dht_msg->desired_replication_level);
4464 msg_ctx.msg_options = ntohl (dht_msg->options); 4508 msg_ctx.msg_options = ntohl (dht_msg->options);
4509 if (GNUNET_DHT_RO_RECORD_ROUTE == (msg_ctx.msg_options & GNUNET_DHT_RO_RECORD_ROUTE))
4510 {
4511 msg_ctx.path_history = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity));
4512 memcpy(msg_ctx.path_history, &my_identity, sizeof(struct GNUNET_PeerIdentity));
4513 msg_ctx.path_history_len = 1;
4514 }
4465 msg_ctx.network_size = estimate_diameter (); 4515 msg_ctx.network_size = estimate_diameter ();
4466 msg_ctx.peer = &my_identity; 4516 msg_ctx.peer = &my_identity;
4467 msg_ctx.importance = DHT_DEFAULT_P2P_IMPORTANCE + 4; /* Make local routing a higher priority */ 4517 msg_ctx.importance = DHT_DEFAULT_P2P_IMPORTANCE + 4; /* Make local routing a higher priority */
@@ -4501,6 +4551,7 @@ handle_dht_local_route_request (void *cls,
4501#endif 4551#endif
4502 } 4552 }
4503 GNUNET_SERVER_receive_done (client, GNUNET_OK); 4553 GNUNET_SERVER_receive_done (client, GNUNET_OK);
4554 GNUNET_free_non_null(msg_ctx.path_history);
4504 return; 4555 return;
4505 } 4556 }
4506 4557
@@ -4658,6 +4709,8 @@ handle_dht_p2p_route_request (void *cls,
4658 struct GNUNET_MessageHeader *enc_msg = 4709 struct GNUNET_MessageHeader *enc_msg =
4659 (struct GNUNET_MessageHeader *) &incoming[1]; 4710 (struct GNUNET_MessageHeader *) &incoming[1];
4660 struct DHT_MessageContext *msg_ctx; 4711 struct DHT_MessageContext *msg_ctx;
4712 char *route_path;
4713 int path_size;
4661 4714
4662 if (ntohs (enc_msg->type) == GNUNET_MESSAGE_TYPE_DHT_P2P_PING) /* Throw these away. FIXME: Don't throw these away? (reply) */ 4715 if (ntohs (enc_msg->type) == GNUNET_MESSAGE_TYPE_DHT_P2P_PING) /* Throw these away. FIXME: Don't throw these away? (reply) */
4663 { 4716 {
@@ -4721,6 +4774,20 @@ handle_dht_p2p_route_request (void *cls,
4721 msg_ctx->replication = ntohl (incoming->desired_replication_level); 4774 msg_ctx->replication = ntohl (incoming->desired_replication_level);
4722 msg_ctx->unique_id = GNUNET_ntohll (incoming->unique_id); 4775 msg_ctx->unique_id = GNUNET_ntohll (incoming->unique_id);
4723 msg_ctx->msg_options = ntohl (incoming->options); 4776 msg_ctx->msg_options = ntohl (incoming->options);
4777 if (GNUNET_DHT_RO_RECORD_ROUTE == (msg_ctx->msg_options & GNUNET_DHT_RO_RECORD_ROUTE))
4778 {
4779 path_size = ntohl(incoming->route_path_length) * sizeof(struct GNUNET_PeerIdentity);
4780 GNUNET_assert(ntohs(message->size) ==
4781 (sizeof(struct GNUNET_DHT_P2PRouteMessage) +
4782 ntohs(enc_msg->size) +
4783 path_size));
4784 route_path = (char *)&incoming[1];
4785 route_path = route_path + ntohs(enc_msg->size);
4786 msg_ctx->path_history = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity) + path_size);
4787 memcpy(msg_ctx->path_history, route_path, path_size);
4788 memcpy(&msg_ctx->path_history[path_size], &my_identity, sizeof(struct GNUNET_PeerIdentity));
4789 msg_ctx->path_history_len = ntohl(incoming->route_path_length) + 1;
4790 }
4724 msg_ctx->network_size = ntohl (incoming->network_size); 4791 msg_ctx->network_size = ntohl (incoming->network_size);
4725 msg_ctx->peer = peer; 4792 msg_ctx->peer = peer;
4726 msg_ctx->importance = DHT_DEFAULT_P2P_IMPORTANCE; 4793 msg_ctx->importance = DHT_DEFAULT_P2P_IMPORTANCE;
@@ -4799,6 +4866,22 @@ handle_dht_p2p_route_result (void *cls,
4799 msg_ctx.peer = peer; 4866 msg_ctx.peer = peer;
4800 msg_ctx.importance = DHT_DEFAULT_P2P_IMPORTANCE + 2; /* Make result routing a higher priority */ 4867 msg_ctx.importance = DHT_DEFAULT_P2P_IMPORTANCE + 2; /* Make result routing a higher priority */
4801 msg_ctx.timeout = DHT_DEFAULT_P2P_TIMEOUT; 4868 msg_ctx.timeout = DHT_DEFAULT_P2P_TIMEOUT;
4869 if ((GNUNET_DHT_RO_RECORD_ROUTE == (msg_ctx.msg_options & GNUNET_DHT_RO_RECORD_ROUTE)) && (ntohl (incoming->outgoing_path_length) > 0))
4870 {
4871 if (ntohs(message->size) - sizeof(struct GNUNET_DHT_P2PRouteResultMessage) - ntohs(enc_msg->size) !=
4872 ntohl (incoming->outgoing_path_length) * sizeof(struct GNUNET_PeerIdentity))
4873 {
4874 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Return message indicated a path was included, but sizes are wrong!\nTotal message size %d, enc_msg size %d, left over %d, expected %d\n",
4875 ntohs(message->size), ntohs(enc_msg->size),
4876 ntohs(message->size) - sizeof(struct GNUNET_DHT_P2PRouteResultMessage) - ntohs(enc_msg->size),
4877 ntohl(incoming->outgoing_path_length) * sizeof(struct GNUNET_PeerIdentity));
4878 return GNUNET_NO;
4879 }
4880
4881 msg_ctx.path_history = (char *)&incoming[1];
4882 msg_ctx.path_history += ntohs(enc_msg->size);
4883 msg_ctx.path_history_len = ntohl (incoming->outgoing_path_length);
4884 }
4802 route_result_message (enc_msg, &msg_ctx); 4885 route_result_message (enc_msg, &msg_ctx);
4803 return GNUNET_YES; 4886 return GNUNET_YES;
4804} 4887}
@@ -5236,7 +5319,7 @@ run (void *cls,
5236 } 5319 }
5237#endif 5320#endif
5238 5321
5239 converge_option = DHT_CONVERGE_SQUARE; 5322 converge_option = DHT_CONVERGE_BINARY;
5240 if (GNUNET_YES == 5323 if (GNUNET_YES ==
5241 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "converge_linear")) 5324 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "converge_linear"))
5242 { 5325 {
@@ -5261,6 +5344,7 @@ run (void *cls,
5261 converge_option = DHT_CONVERGE_BINARY; 5344 converge_option = DHT_CONVERGE_BINARY;
5262 } 5345 }
5263 5346
5347 converge_modifier = 4.0;
5264 if (GNUNET_OK == 5348 if (GNUNET_OK ==
5265 GNUNET_CONFIGURATION_get_value_string (cfg, "dht", "converge_modifier", 5349 GNUNET_CONFIGURATION_get_value_string (cfg, "dht", "converge_modifier",
5266 &converge_modifier_buf)) 5350 &converge_modifier_buf))