aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorSupriti Singh <supritisingh08@gmail.com>2014-04-13 11:54:17 +0000
committerSupriti Singh <supritisingh08@gmail.com>2014-04-13 11:54:17 +0000
commitc004e39e12ae8064a898bc218246c2eb379b1a9a (patch)
tree0a8a3c1c901f8b8bbe95dc033b08c9e673f57283 /src/dht
parent1c97f54080bfd543a6000fb3fe3008cb2060fd54 (diff)
downloadgnunet-c004e39e12ae8064a898bc218246c2eb379b1a9a.tar.gz
gnunet-c004e39e12ae8064a898bc218246c2eb379b1a9a.zip
Framework for trail rejection and threshold on links
first phase changes for get.
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/gnunet-service-xdht_clients.c28
-rw-r--r--src/dht/gnunet-service-xdht_datacache.c100
-rw-r--r--src/dht/gnunet-service-xdht_datacache.h12
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c928
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.h70
-rw-r--r--src/dht/gnunet-service-xdht_routing.c43
-rw-r--r--src/dht/gnunet-service-xdht_routing.h10
7 files changed, 875 insertions, 316 deletions
diff --git a/src/dht/gnunet-service-xdht_clients.c b/src/dht/gnunet-service-xdht_clients.c
index d3b920551..17c95cc4c 100644
--- a/src/dht/gnunet-service-xdht_clients.c
+++ b/src/dht/gnunet-service-xdht_clients.c
@@ -843,15 +843,14 @@ transmit_request (struct ClientQueryRecord *cqr)
843 GNUNET_h2s (&cqr->key), 843 GNUNET_h2s (&cqr->key),
844 cqr->replication, 844 cqr->replication,
845 cqr->seen_replies_count); 845 cqr->seen_replies_count);
846
847 /* FIXME: Here I am passing NULL for parameters check if its correct or
848 not. */
846#if 0 849#if 0
847 /* FIXME: Change it to your own handle_get. */
848 GDS_NEIGHBOURS_handle_get (cqr->type, cqr->msg_options, cqr->replication, 850 GDS_NEIGHBOURS_handle_get (cqr->type, cqr->msg_options, cqr->replication,
849 0 /* hop count */ , 851 0 /* hop count */ ,NULL, NULL, 0,
850 &cqr->key, cqr->xquery, cqr->xquery_size, reply_bf, 852 &cqr->key, NULL, NULL, 0);
851 reply_bf_mutator, peer_bf); 853#endif
852#endif
853
854
855 /* exponential back-off for retries. 854 /* exponential back-off for retries.
856 * max GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */ 855 * max GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */
857 cqr->retry_frequency = GNUNET_TIME_STD_BACKOFF (cqr->retry_frequency); 856 cqr->retry_frequency = GNUNET_TIME_STD_BACKOFF (cqr->retry_frequency);
@@ -940,14 +939,14 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client,
940 ntohl (put_msg->type), 939 ntohl (put_msg->type),
941 size - sizeof (struct GNUNET_DHT_ClientPutMessage), 940 size - sizeof (struct GNUNET_DHT_ClientPutMessage),
942 &put_msg[1]); 941 &put_msg[1]);
943 /* store locally */ 942 /* FIXME: Should we store locally? */
944 GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put_msg->expiration), 943 GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put_msg->expiration),
945 &put_msg->key, 0, NULL, ntohl (put_msg->type), 944 &put_msg->key, 0, NULL, ntohl (put_msg->type),
946 size - sizeof (struct GNUNET_DHT_ClientPutMessage), 945 size - sizeof (struct GNUNET_DHT_ClientPutMessage),
947 &put_msg[1]); 946 &put_msg[1]);
948 947
949 /* FIXME: At the moment we don't use replication in x-vine. But keep it for 948 /* FIXME: Is it correct to pass NULL for current destination and current
950 time being. Check all the fields again. */ 949 source. */
951 GDS_NEIGHBOURS_handle_put (ntohl (put_msg->type), ntohl (put_msg->options), 950 GDS_NEIGHBOURS_handle_put (ntohl (put_msg->type), ntohl (put_msg->options),
952 ntohl (put_msg->desired_replication_level), 951 ntohl (put_msg->desired_replication_level),
953 GNUNET_TIME_absolute_ntoh (put_msg->expiration), 952 GNUNET_TIME_absolute_ntoh (put_msg->expiration),
@@ -955,7 +954,7 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client,
955 &put_msg->key, 0, NULL, &put_msg[1], 954 &put_msg->key, 0, NULL, &put_msg[1],
956 size - 955 size -
957 sizeof (struct GNUNET_DHT_ClientPutMessage), 956 sizeof (struct GNUNET_DHT_ClientPutMessage),
958 NULL, 0, NULL); 957 NULL, NULL, 0, NULL);
959 958
960 GDS_CLIENTS_process_put (ntohl (put_msg->options), 959 GDS_CLIENTS_process_put (ntohl (put_msg->options),
961 ntohl (put_msg->type), 960 ntohl (put_msg->type),
@@ -1047,9 +1046,12 @@ handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client,
1047 if (GNUNET_SCHEDULER_NO_TASK != retry_task) 1046 if (GNUNET_SCHEDULER_NO_TASK != retry_task)
1048 GNUNET_SCHEDULER_cancel (retry_task); 1047 GNUNET_SCHEDULER_cancel (retry_task);
1049 retry_task = GNUNET_SCHEDULER_add_now (&transmit_next_request_task, NULL); 1048 retry_task = GNUNET_SCHEDULER_add_now (&transmit_next_request_task, NULL);
1050 /* perform local lookup */ 1049 /* perform local lookup
1050 * FIXME: Should we call it here or in neighbours file. And how to handle
1051 * this case where we may get the data locally. You really need to rethink
1052 * this design again.
1051 GDS_DATACACHE_handle_get (&get->key, cqr->type, cqr->xquery, xquery_size, 1053 GDS_DATACACHE_handle_get (&get->key, cqr->type, cqr->xquery, xquery_size,
1052 NULL, 0); 1054 NULL, 0); */
1053 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1055 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1054} 1056}
1055 1057
diff --git a/src/dht/gnunet-service-xdht_datacache.c b/src/dht/gnunet-service-xdht_datacache.c
index 77673cf66..df2e17187 100644
--- a/src/dht/gnunet-service-xdht_datacache.c
+++ b/src/dht/gnunet-service-xdht_datacache.c
@@ -19,7 +19,7 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file dht/gnunet-service-xdht_datacache.c 22 * @file dht/gnunet-service-dht_datacache.c
23 * @brief GNUnet DHT service's datacache integration 23 * @brief GNUnet DHT service's datacache integration
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * @author Nathan Evans 25 * @author Nathan Evans
@@ -29,7 +29,8 @@
29#include "gnunet-service-xdht_clients.h" 29#include "gnunet-service-xdht_clients.h"
30#include "gnunet-service-xdht_datacache.h" 30#include "gnunet-service-xdht_datacache.h"
31#include "gnunet-service-xdht_routing.h" 31#include "gnunet-service-xdht_routing.h"
32#include "gnunet-service-xdht.h" 32#include "gnunet-service-xdht_neighbours.h"
33#include "gnunet-service-dht.h"
33 34
34#define LOG(kind,...) GNUNET_log_from (kind, "dht-dtcache",__VA_ARGS__) 35#define LOG(kind,...) GNUNET_log_from (kind, "dht-dtcache",__VA_ARGS__)
35 36
@@ -61,7 +62,7 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
61 const void *data) 62 const void *data)
62{ 63{
63 int r; 64 int r;
64 65
65 if (NULL == datacache) 66 if (NULL == datacache)
66 { 67 {
67 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 68 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -84,6 +85,27 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
84 GNUNET_h2s (key), data_size, r, put_path_length); 85 GNUNET_h2s (key), data_size, r, put_path_length);
85} 86}
86 87
88/**
89 * List of peers in the get path.
90 */
91struct GetPath
92{
93 /**
94 * Pointer to next item in the list
95 */
96 struct GetPath *next;
97
98 /**
99 * Pointer to previous item in the list
100 */
101 struct GetPath *prev;
102
103 /**
104 * An element in the get path.
105 */
106 struct GNUNET_PeerIdentity peer;
107};
108
87 109
88/** 110/**
89 * Context containing information about a GET request. 111 * Context containing information about a GET request.
@@ -114,11 +136,37 @@ struct GetRequestContext
114 * Mutator value for the reply_bf, see gnunet_block_lib.h 136 * Mutator value for the reply_bf, see gnunet_block_lib.h
115 */ 137 */
116 uint32_t reply_bf_mutator; 138 uint32_t reply_bf_mutator;
117 139
140 /**
141 * Total number of peers in get path.
142 */
143 unsigned int get_path_length;
144
118 /** 145 /**
119 * Return value to give back. 146 * Return value to give back.
120 */ 147 */
121 enum GNUNET_BLOCK_EvaluationResult eval; 148 enum GNUNET_BLOCK_EvaluationResult eval;
149
150 /**
151 *
152 */
153 unsigned int current_trail_index;
154
155 /**
156 *
157 */
158 struct GNUNET_PeerIdentity next_hop;
159
160 /**
161 * Head of trail to reach this finger.
162 */
163 struct GetPath *head;
164
165 /**
166 * Tail of trail to reach this finger.
167 */
168 struct GetPath *tail;
169 /* get_path */
122}; 170};
123 171
124 172
@@ -163,9 +211,22 @@ datacache_get_iterator (void *cls,
163 GNUNET_STATISTICS_update (GDS_stats, 211 GNUNET_STATISTICS_update (GDS_stats,
164 gettext_noop 212 gettext_noop
165 ("# Good RESULTS found in datacache"), 1, 213 ("# Good RESULTS found in datacache"), 1,
166 GNUNET_NO); 214 GNUNET_NO);
167 /* GDS_CLIENTS_handle_reply (exp, key, 0, NULL, put_path_length, put_path, 215 struct GNUNET_PeerIdentity *get_path;
168 type, size, data);*/ 216 get_path = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
217 struct GetPath *iterator;
218 iterator = ctx->head;
219 int i = 0;
220 while (i < ctx->get_path_length)
221 {
222 memcpy (&get_path[i], &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
223 i++;
224 iterator = iterator->next;
225 }
226 GDS_NEIGHBOURS_send_get_result (exp, key, put_path_length, put_path,
227 type, size, data, get_path, ctx->get_path_length,
228 ctx->current_trail_index, &(ctx->next_hop));
229
169 /* forward to other peers */ 230 /* forward to other peers */
170 GDS_ROUTING_process (type, exp, key, put_path_length, put_path, 0, NULL, 231 GDS_ROUTING_process (type, exp, key, put_path_length, put_path, 0, NULL,
171 data, size); 232 data, size);
@@ -217,13 +278,19 @@ datacache_get_iterator (void *cls,
217 * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL 278 * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL
218 * @param reply_bf_mutator mutation value for reply_bf 279 * @param reply_bf_mutator mutation value for reply_bf
219 * @return evaluation result for the local replies 280 * @return evaluation result for the local replies
281 * @get_path_length Total number of peers in get path
282 * @get_path Peers in get path.
220 */ 283 */
221enum GNUNET_BLOCK_EvaluationResult 284enum GNUNET_BLOCK_EvaluationResult
222GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key, 285GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key,
223 enum GNUNET_BLOCK_Type type, const void *xquery, 286 enum GNUNET_BLOCK_Type type, const void *xquery,
224 size_t xquery_size, 287 size_t xquery_size,
225 struct GNUNET_CONTAINER_BloomFilter **reply_bf, 288 struct GNUNET_CONTAINER_BloomFilter **reply_bf,
226 uint32_t reply_bf_mutator) 289 uint32_t reply_bf_mutator,
290 uint32_t get_path_length,
291 struct GNUNET_PeerIdentity *get_path,
292 unsigned int current_trail_index,
293 struct GNUNET_PeerIdentity *next_hop)
227{ 294{
228 struct GetRequestContext ctx; 295 struct GetRequestContext ctx;
229 unsigned int r; 296 unsigned int r;
@@ -239,6 +306,23 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key,
239 ctx.xquery_size = xquery_size; 306 ctx.xquery_size = xquery_size;
240 ctx.reply_bf = reply_bf; 307 ctx.reply_bf = reply_bf;
241 ctx.reply_bf_mutator = reply_bf_mutator; 308 ctx.reply_bf_mutator = reply_bf_mutator;
309 ctx.get_path_length = get_path_length;
310 memcpy (&(ctx.next_hop), next_hop, sizeof (struct GNUNET_PeerIdentity));
311 ctx.current_trail_index = current_trail_index;
312 /* FIXME: add the get path into ctx and then call gds_neighbours_handle_get*/
313 int i = 0;
314 while (i < get_path_length)
315 {
316 struct GetPath *element;
317 element = GNUNET_malloc (sizeof (struct GetPath));
318 element->next = NULL;
319 element->prev = NULL;
320
321 memcpy (&(element->peer), &get_path[i], sizeof(struct GNUNET_PeerIdentity));
322 GNUNET_CONTAINER_DLL_insert_tail(ctx.head, ctx.tail, element);
323 i++;
324 }
325
242 r = GNUNET_DATACACHE_get (datacache, key, type, &datacache_get_iterator, 326 r = GNUNET_DATACACHE_get (datacache, key, type, &datacache_get_iterator,
243 &ctx); 327 &ctx);
244 LOG (GNUNET_ERROR_TYPE_DEBUG, 328 LOG (GNUNET_ERROR_TYPE_DEBUG,
diff --git a/src/dht/gnunet-service-xdht_datacache.h b/src/dht/gnunet-service-xdht_datacache.h
index b30359124..38515d062 100644
--- a/src/dht/gnunet-service-xdht_datacache.h
+++ b/src/dht/gnunet-service-xdht_datacache.h
@@ -19,13 +19,13 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file dht/gnunet-service-xdht_datacache.h 22 * @file dht/gnunet-service-dht_datacache.h
23 * @brief GNUnet DHT service's datacache integration 23 * @brief GNUnet DHT service's datacache integration
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * @author Nathan Evans 25 * @author Nathan Evans
26 */ 26 */
27#ifndef GNUNET_SERVICE_XDHT_DATACACHE_H 27#ifndef GNUNET_SERVICE_DHT_DATACACHE_H
28#define GNUNET_SERVICE_XDHT_DATACACHE_H 28#define GNUNET_SERVICE_DHT_DATACACHE_H
29 29
30#include "gnunet_util_lib.h" 30#include "gnunet_util_lib.h"
31#include "gnunet_block_lib.h" 31#include "gnunet_block_lib.h"
@@ -67,7 +67,11 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key,
67 enum GNUNET_BLOCK_Type type, const void *xquery, 67 enum GNUNET_BLOCK_Type type, const void *xquery,
68 size_t xquery_size, 68 size_t xquery_size,
69 struct GNUNET_CONTAINER_BloomFilter **reply_bf, 69 struct GNUNET_CONTAINER_BloomFilter **reply_bf,
70 uint32_t reply_bf_mutator); 70 uint32_t reply_bf_mutator,
71 uint32_t get_path_length,
72 struct GNUNET_PeerIdentity *get_path,
73 unsigned int current_trail_index,
74 struct GNUNET_PeerIdentity *next_hop);
71 75
72 76
73/** 77/**
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c
index 0dad53fc5..8d99d5414 100644
--- a/src/dht/gnunet-service-xdht_neighbours.c
+++ b/src/dht/gnunet-service-xdht_neighbours.c
@@ -49,6 +49,8 @@
49#include "dht.h" 49#include "dht.h"
50 50
51/* TODO: 51/* TODO:
52 * 1. when should we use const struct and replace wherever needed.
53 * 2. use assert for each function where you need to check the return value.
52 1. Use a global array of all known peers in find_successor, Only when 54 1. Use a global array of all known peers in find_successor, Only when
53 a new peer is added in finger or friend peer map, then re calculate 55 a new peer is added in finger or friend peer map, then re calculate
54 the array. Or else use the old one. 56 the array. Or else use the old one.
@@ -118,7 +120,7 @@ struct PeerPutMessage
118 /** 120 /**
119 * Content type. 121 * Content type.
120 */ 122 */
121 uint32_t type GNUNET_PACKED; 123 uint32_t block_type GNUNET_PACKED;
122 124
123 /** 125 /**
124 * Hop count 126 * Hop count
@@ -135,18 +137,18 @@ struct PeerPutMessage
135 */ 137 */
136 uint32_t put_path_length GNUNET_PACKED; 138 uint32_t put_path_length GNUNET_PACKED;
137 139
138 /**
139 * Source peer
140 */
141 struct GNUNET_PeerIdentity source_peer;
142
143 /** 140 /**
144 * Current destination 141 * Current destination to which this message is forwarded.
145 */ 142 */
146 struct GNUNET_PeerIdentity current_destination; 143 struct GNUNET_PeerIdentity current_destination;
147 144
145 /**
146 * Peer whose finger is current_destination.
147 */
148 struct GNUNET_PeerIdentity current_source;
149
148 /** 150 /**
149 * Current destination type 151 * current_destination type.
150 */ 152 */
151 enum current_destination_type current_destination_type; 153 enum current_destination_type current_destination_type;
152 154
@@ -179,6 +181,11 @@ struct PeerGetResultMessage
179 struct GNUNET_MessageHeader header; 181 struct GNUNET_MessageHeader header;
180 182
181 /** 183 /**
184 * The type for the data.
185 */
186 uint32_t type GNUNET_PACKED;
187
188 /**
182 * Peer which is sending get result message. 189 * Peer which is sending get result message.
183 */ 190 */
184 struct GNUNET_PeerIdentity source_peer; 191 struct GNUNET_PeerIdentity source_peer;
@@ -192,6 +199,16 @@ struct PeerGetResultMessage
192 * Current index in get path. 199 * Current index in get path.
193 */ 200 */
194 unsigned int current_path_index; 201 unsigned int current_path_index;
202 /**
203 * Number of peers recorded in the outgoing path from source to the
204 * storgage location of this message.
205 */
206 uint32_t put_path_length GNUNET_PACKED;
207
208 /**
209 * When does this entry expire?
210 */
211 struct GNUNET_TIME_AbsoluteNBO expiration;
195 212
196 /** 213 /**
197 * Length of the GET path that follows (if tracked). 214 * Length of the GET path that follows (if tracked).
@@ -228,33 +245,44 @@ struct PeerGetMessage
228 struct GNUNET_MessageHeader header; 245 struct GNUNET_MessageHeader header;
229 246
230 /** 247 /**
231 * Source peer 248 * Processing options
232 */ 249 */
233 struct GNUNET_PeerIdentity source_peer; 250 uint32_t options GNUNET_PACKED;
234 251
235 /** 252 /**
253 * Desired content type.
254 */
255 uint32_t block_type GNUNET_PACKED;
256
257 /**
258 * Hop count
259 */
260 uint32_t hop_count GNUNET_PACKED;
261
262 /**
263 * Desired replication level for this request.
264 */
265 uint32_t desired_replication_level GNUNET_PACKED;
266
267 /**
236 * Total number of peers in get path. 268 * Total number of peers in get path.
237 */ 269 */
238 unsigned int get_path_length; 270 unsigned int get_path_length;
239 271
240 /** 272 /**
241 * 273 * Peer which is an intermediate destination.
242 */ 274 */
243 struct GNUNET_PeerIdentity current_destination; 275 struct GNUNET_PeerIdentity current_destination;
244
245 /**
246 *
247 */
248 enum current_destination_type current_dest_type;
249 276
250 /** 277 /**
251 * Unique identifier of the request. 278 * Source for which current_destination is the finger.
252 */ 279 */
253 uint64_t request_id; 280 struct GNUNET_PeerIdentity current_source;
281
254 /** 282 /**
255 * When does the content expire? 283 * Type of current destination
256 */ 284 */
257 struct GNUNET_TIME_AbsoluteNBO expiration_time; 285 enum current_destination_type current_dest_type;
258 286
259 /** 287 /**
260 * The key we are looking for. 288 * The key we are looking for.
@@ -298,6 +326,13 @@ struct PeerTrailSetupMessage
298 struct GNUNET_PeerIdentity current_destination; 326 struct GNUNET_PeerIdentity current_destination;
299 327
300 /** 328 /**
329 * In case the packet is forwarded to an intermediate finger, then
330 * current_source contains the peer id whose finger is the intermediate
331 * finger. In case the packet is forwarded to a friend, then it is NULL.
332 */
333 struct GNUNET_PeerIdentity current_source;
334
335 /**
301 * Index into finger peer map. 336 * Index into finger peer map.
302 */ 337 */
303 unsigned int finger_map_index; 338 unsigned int finger_map_index;
@@ -348,6 +383,44 @@ struct PeerTrailSetupResultMessage
348 383
349}; 384};
350 385
386/**
387 *
388 */
389struct PeerTrailRejectionMessage
390{
391 /**
392 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION
393 */
394 struct GNUNET_MessageHeader header;
395
396 /**
397 * Source peer which wants to set up the trail.
398 */
399 struct GNUNET_PeerIdentity source_peer;
400
401 /**
402 * Finger identity value.
403 */
404 uint64_t finger_identity;
405
406 /**
407 * Peer which sent trail rejection message.
408 */
409 struct GNUNET_PeerIdentity congested_peer;
410
411 /**
412 * Index in finger peer map of source peer.
413 */
414 unsigned int finger_map_index;
415
416 /**
417 * Total number of peers in the trail.
418 */
419 unsigned int trail_length;
420
421 /* trail_list */
422};
423
351 424
352/** 425/**
353 * P2P Verify Successor message. 426 * P2P Verify Successor message.
@@ -573,7 +646,7 @@ struct FingerInfo
573 unsigned int finger_map_index; 646 unsigned int finger_map_index;
574 647
575 /** 648 /**
576 * Total number of entries in trail from [me,finger] 649 * Total number of entries in trail from (me,finger]
577 */ 650 */
578 unsigned int trail_length; 651 unsigned int trail_length;
579 652
@@ -614,6 +687,30 @@ struct Sorting_List
614 687
615 688
616/** 689/**
690 * FIXME: Think of better comments.
691 * An entry in Failed_Trail_List
692 */
693struct FailedTrail
694{
695 /**
696 * Source peer which was trying to setup up the trail to @a destination_finger_value
697 */
698 struct GNUNET_PeerIdentity source_peer;
699
700 /**
701 * Value to which we were trying to find the closest successor.
702 */
703 uint64_t destination_finger_value;
704
705 /**
706 * Peer which has crossed the threshold limit on its routing table size.
707 */
708 struct GNUNET_PeerIdentity congested_peer;
709
710};
711
712
713/**
617 * Task that sends FIND FINGER TRAIL requests. 714 * Task that sends FIND FINGER TRAIL requests.
618 */ 715 */
619static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task; 716static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task;
@@ -640,6 +737,11 @@ static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
640static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap; 737static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap;
641 738
642/** 739/**
740 * Hash maps of all the trail which failed due to a congested peer.
741 */
742static struct GNUNET_CONTAINER_MultiPeerMap *failed_trail_list;
743
744/**
643 * Handle to CORE. 745 * Handle to CORE.
644 */ 746 */
645static struct GNUNET_CORE_Handle *core_api; 747static struct GNUNET_CORE_Handle *core_api;
@@ -754,11 +856,13 @@ process_friend_queue (struct FriendInfo *peer)
754} 856}
755 857
756 858
757/** 859/**FIXME: add better comment for current_source which shows its relation
860 * with current_destination.
758 * Construct a trail message and forward it to a friend. 861 * Construct a trail message and forward it to a friend.
759 * @param source_peer Peer which wants to set up the trail to one of its finger. 862 * @param source_peer Peer which wants to set up the trail to one of its finger.
760 * @param destination_finger Value whose successor we are searching the network. 863 * @param destination_finger Value whose successor we are searching the network.
761 * @param current_destination Peer which gets this message. 864 * @param current_destination Peer which gets this message.
865 * @param current_source Peer for which current_destination is its finger.
762 * @param target_friend Current friend to which this message should be forwarded. 866 * @param target_friend Current friend to which this message should be forwarded.
763 * @param trail_length Numbers of peers in the trail. 867 * @param trail_length Numbers of peers in the trail.
764 * @param trail_peer_list peers this request has traversed so far 868 * @param trail_peer_list peers this request has traversed so far
@@ -769,6 +873,7 @@ void
769GDS_NEIGHBOURS_send_trail_setup (struct GNUNET_PeerIdentity *source_peer, 873GDS_NEIGHBOURS_send_trail_setup (struct GNUNET_PeerIdentity *source_peer,
770 uint64_t destination_finger, 874 uint64_t destination_finger,
771 struct GNUNET_PeerIdentity *current_destination, 875 struct GNUNET_PeerIdentity *current_destination,
876 struct GNUNET_PeerIdentity *current_source,
772 struct FriendInfo *target_friend, 877 struct FriendInfo *target_friend,
773 unsigned int trail_length, 878 unsigned int trail_length,
774 struct GNUNET_PeerIdentity *trail_peer_list, 879 struct GNUNET_PeerIdentity *trail_peer_list,
@@ -805,6 +910,9 @@ GDS_NEIGHBOURS_send_trail_setup (struct GNUNET_PeerIdentity *source_peer,
805 memcpy (&(tsm->destination_finger), &destination_finger, sizeof (uint64_t)); 910 memcpy (&(tsm->destination_finger), &destination_finger, sizeof (uint64_t));
806 memcpy (&(tsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); 911 memcpy (&(tsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
807 memcpy (&(tsm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity)); 912 memcpy (&(tsm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
913 /* FIXME: Is it correct to use NULL here for comparison? */
914 if (current_source != NULL)
915 memcpy (&(tsm->current_source), current_source, sizeof (struct GNUNET_PeerIdentity));
808 tsm->current_destination_type = htonl (type); 916 tsm->current_destination_type = htonl (type);
809 tsm->trail_length = htonl (trail_length); 917 tsm->trail_length = htonl (trail_length);
810 tsm->finger_map_index = htonl (finger_map_index); 918 tsm->finger_map_index = htonl (finger_map_index);
@@ -1075,7 +1183,7 @@ GDS_NEIGHBOURS_send_notify_new_successor (struct GNUNET_PeerIdentity *source_pee
1075 * @return Friend 1183 * @return Friend
1076 */ 1184 */
1077static struct FriendInfo * 1185static struct FriendInfo *
1078select_random_friend() 1186select_random_friend (struct GNUNET_PeerIdentity *congested_peer)
1079{ 1187{
1080 unsigned int current_size; 1188 unsigned int current_size;
1081 unsigned int *index; 1189 unsigned int *index;
@@ -1099,7 +1207,18 @@ select_random_friend()
1099 } 1207 }
1100 1208
1101 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend)) 1209 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend))
1210 {
1211 /* TODO: Here you have chosen a random friend. Now you should check the size
1212 of its routing table size, and if its more than threshold, then check which
1213 of the entries has trail length greater than trail length threshold. we
1214 should without checking the routing table size also we should check the
1215 trail with trail length greater than threshold. then
1216 you should try to find a new route through this new node that has joined in
1217 only for those finger entries whose trail length is greater than threshold.
1218 But I don't want the new node to wait for this process to get over. so
1219 should i declare a function which will be called after some interval.*/
1102 return friend; 1220 return friend;
1221 }
1103 else 1222 else
1104 return NULL; 1223 return NULL;
1105} 1224}
@@ -1251,17 +1370,18 @@ send_find_finger_trail_message (void *cls,
1251 } 1370 }
1252 1371
1253 select_friend: 1372 select_friend:
1254 /* FIXME: Here should we choose randomly or not. */ 1373 target_friend = select_random_friend (NULL);
1255 target_friend = select_random_friend();
1256 1374
1257 finger_map_index = current_finger_index; 1375 finger_map_index = current_finger_index;
1258 current_finger_index = ( current_finger_index + 1) % MAX_FINGERS; 1376 current_finger_index = ( current_finger_index + 1) % MAX_FINGERS;
1259 1377
1260 if(NULL != target_friend) 1378 if(NULL != target_friend)
1261 { 1379 {
1380 /* FIXME: Here I am passing NULL for current source, is it correct?
1381 also, we set the current source only if current_destination_type
1382 is finger. */
1262 GDS_NEIGHBOURS_send_trail_setup (&my_identity, *finger_identity, &(target_friend->id), 1383 GDS_NEIGHBOURS_send_trail_setup (&my_identity, *finger_identity, &(target_friend->id),
1263 target_friend, 0, NULL, 1384 NULL, target_friend, 0, NULL, finger_map_index, FRIEND);
1264 finger_map_index, FRIEND);
1265 } 1385 }
1266 1386
1267 /* FIXME: How to decide the correct interval? */ 1387 /* FIXME: How to decide the correct interval? */
@@ -1390,7 +1510,6 @@ core_init (void *cls,
1390{ 1510{
1391 my_identity = *identity; 1511 my_identity = *identity;
1392 1512
1393#if 0
1394 /* SUPU TEST CODE */ 1513 /* SUPU TEST CODE */
1395 struct GNUNET_PeerIdentity *print_peer; 1514 struct GNUNET_PeerIdentity *print_peer;
1396 print_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 1515 print_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
@@ -1398,7 +1517,7 @@ core_init (void *cls,
1398 FPRINTF (stderr,_("\nSUPU %s, %s, %d,my_identity = %s"), 1517 FPRINTF (stderr,_("\nSUPU %s, %s, %d,my_identity = %s"),
1399 __FILE__, __func__,__LINE__, GNUNET_i2s (print_peer)); 1518 __FILE__, __func__,__LINE__, GNUNET_i2s (print_peer));
1400 /* SUPU TEST CODE ENDS */ 1519 /* SUPU TEST CODE ENDS */
1401#endif 1520
1402} 1521}
1403 1522
1404 1523
@@ -1443,7 +1562,6 @@ invert_trail_list (struct GNUNET_PeerIdentity *destination_peer,
1443 * @param new_finger 1562 * @param new_finger
1444 * @return 1563 * @return
1445 */ 1564 */
1446#if 0
1447static int 1565static int
1448compare_finger_identity (struct GNUNET_PeerIdentity *existing_finger, 1566compare_finger_identity (struct GNUNET_PeerIdentity *existing_finger,
1449 struct GNUNET_PeerIdentity *new_finger) 1567 struct GNUNET_PeerIdentity *new_finger)
@@ -1453,16 +1571,16 @@ compare_finger_identity (struct GNUNET_PeerIdentity *existing_finger,
1453 (existing_finger == new_finger) ? 0 : -1; 1571 (existing_finger == new_finger) ? 0 : -1;
1454 return ret; 1572 return ret;
1455} 1573}
1456#endif 1574
1457 1575
1458/** 1576/**
1459 * FIXME: Not sure of the logic to find the correct predecessor. 1577 * FIXME: Not sure of the logic to find the correct predecessor
1578 * I think logic of this code is wrong everything else seems to be correct.
1460 * Given two finger identities, find the closest predecessor. 1579 * Given two finger identities, find the closest predecessor.
1461 * @param existing_predecessor 1580 * @param existing_predecessor
1462 * @param new_predecessor 1581 * @param new_predecessor
1463 * @return 1582 * @return
1464 */ 1583 */
1465#if 0
1466static int 1584static int
1467compare_predecessor(struct GNUNET_PeerIdentity *existing_predecessor, 1585compare_predecessor(struct GNUNET_PeerIdentity *existing_predecessor,
1468 struct GNUNET_PeerIdentity *new_predecessor) 1586 struct GNUNET_PeerIdentity *new_predecessor)
@@ -1472,11 +1590,11 @@ compare_predecessor(struct GNUNET_PeerIdentity *existing_predecessor,
1472 (existing_predecessor == new_predecessor) ? 0 : -1; 1590 (existing_predecessor == new_predecessor) ? 0 : -1;
1473 return ret; 1591 return ret;
1474} 1592}
1475#endif 1593
1594
1476 1595
1477/* 1596/*
1478 * Add an entry in finger table. 1597 * Add an entry in finger table.
1479 * Add an entry into finger table
1480 * @param finger_identity Peer identity of finger 1598 * @param finger_identity Peer identity of finger
1481 * @param finger_trail Trail to reach the finger 1599 * @param finger_trail Trail to reach the finger
1482 * @param trail_length Number of peers in the trail. 1600 * @param trail_length Number of peers in the trail.
@@ -1489,15 +1607,15 @@ void finger_table_add (struct GNUNET_PeerIdentity *finger_identity,
1489 unsigned int finger_map_index) 1607 unsigned int finger_map_index)
1490{ 1608{
1491 struct FingerInfo *new_finger_entry; 1609 struct FingerInfo *new_finger_entry;
1610 struct GNUNET_PeerIdentity key_ret;
1492 int i; 1611 int i;
1493#if 0
1494 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; 1612 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1495 struct GNUNET_PeerIdentity key_ret;
1496 struct FingerInfo *existing_finger; 1613 struct FingerInfo *existing_finger;
1497 int finger_index; 1614 int finger_index;
1498 int i;
1499 1615
1500 1616 /* SUPU Here we trying to check if we already have an entry. If yes then we
1617 can keep two trails for redundant routing. if they are different then we
1618 need to choose the closest one. and remove the other one. */
1501 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 1619 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1502 1620
1503 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++) 1621 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
@@ -1505,25 +1623,43 @@ void finger_table_add (struct GNUNET_PeerIdentity *finger_identity,
1505 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret, 1623 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
1506 (const void **)&existing_finger)) 1624 (const void **)&existing_finger))
1507 { 1625 {
1508 /* If we already have an entry at the finger map index. */
1509 if ((finger_map_index == existing_finger->finger_map_index)) 1626 if ((finger_map_index == existing_finger->finger_map_index))
1510 { 1627 {
1511 /* Check if the finger entry are same. */
1512 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),finger_identity)) 1628 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),finger_identity))
1513 { 1629 {
1514 FPRINTF (stderr,_("\nSUPU %s, %s, %d"), __FILE__, __func__,__LINE__); 1630 FPRINTF (stderr,_("\nSUPU Entries are same. %s, %s, %d"), __FILE__, __func__,__LINE__);
1631 /* FIXME: Here you should check if the trail is same. If yes then don't add the entry. it
1632 seems to be very suboptimal. */
1633 if ((existing_finger->trail_length) == trail_length)
1634 {
1635 struct TrailPeerList *iterate;
1636 iterate = existing_finger->head;
1637 int k;
1638 k = 0;
1639 while (k < trail_length)
1640 {
1641 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(iterate->peer), &finger_trail[k]))
1642 {
1643 k++;
1644 iterate = iterate->next;
1645 }
1646 }
1647 if (k == trail_length)
1648 return;
1649 else
1650 goto add_new_entry;
1651 }
1515 goto add_new_entry; 1652 goto add_new_entry;
1516 } 1653 }
1517 else 1654 else
1518 { 1655 {
1519 /* FIXME: here you should have something better to check which finger
1520 is closer one. */
1521 int ret; 1656 int ret;
1522 if (finger_map_index == 1) 1657 if (finger_map_index == 1)
1523 { 1658 {
1524 FPRINTF (stderr,_("\nSUPU %s, %s, %d"), __FILE__, __func__,__LINE__); 1659 FPRINTF (stderr,_("\nSUPUP Predecessor are different %s, %s, %d"), __FILE__, __func__,__LINE__);
1525 ret = compare_predecessor (&(existing_finger->finger_identity), 1660 ret = compare_predecessor (&(existing_finger->finger_identity),
1526 finger_identity); 1661 finger_identity);
1662 goto add_new_entry;
1527 } 1663 }
1528 else 1664 else
1529 { 1665 {
@@ -1533,7 +1669,7 @@ void finger_table_add (struct GNUNET_PeerIdentity *finger_identity,
1533 } 1669 }
1534 if (ret > 0) 1670 if (ret > 0)
1535 { 1671 {
1536 FPRINTF (stderr,_("\nSUPU %s, %s, %d"), __FILE__, __func__,__LINE__); 1672 FPRINTF (stderr,_("\nSUPU Adding the new one and removing the old one %s, %s, %d"), __FILE__, __func__,__LINE__);
1537 GNUNET_assert (GNUNET_YES == 1673 GNUNET_assert (GNUNET_YES ==
1538 GNUNET_CONTAINER_multipeermap_remove (finger_peermap, 1674 GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
1539 &(existing_finger->finger_identity), 1675 &(existing_finger->finger_identity),
@@ -1542,7 +1678,7 @@ void finger_table_add (struct GNUNET_PeerIdentity *finger_identity,
1542 } 1678 }
1543 else 1679 else
1544 { 1680 {
1545 FPRINTF (stderr,_("\nSUPU %s, %s, %d"), __FILE__, __func__,__LINE__); 1681 FPRINTF (stderr,_("\nSUPU Nothing to do return %s, %s, %d"), __FILE__, __func__,__LINE__);
1546 return; 1682 return;
1547 } 1683 }
1548 } 1684 }
@@ -1551,35 +1687,80 @@ void finger_table_add (struct GNUNET_PeerIdentity *finger_identity,
1551 } 1687 }
1552 1688
1553 add_new_entry: 1689 add_new_entry:
1554#endif
1555 new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo)); 1690 new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo));
1556 memcpy (&(new_finger_entry->finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity)); 1691 memcpy (&(new_finger_entry->finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity));
1692 new_finger_entry->finger_map_index = finger_map_index;
1557 1693
1558 i = 0; 1694 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, finger_identity))
1559 while (i < trail_length) 1695 {
1696 /* I am the finger */
1697 new_finger_entry->trail_length = 0;
1698 }
1699 else
1560 { 1700 {
1561 struct TrailPeerList *element; 1701 i = 0;
1562 element = GNUNET_malloc (sizeof (struct TrailPeerList)); 1702 while (i < trail_length)
1563 element->next = NULL; 1703 {
1564 element->prev = NULL; 1704 struct TrailPeerList *element;
1705 element = GNUNET_malloc (sizeof (struct TrailPeerList));
1706 element->next = NULL;
1707 element->prev = NULL;
1565 1708
1566 memcpy (&(element->peer), &finger_trail[i], sizeof(struct GNUNET_PeerIdentity)); 1709 memcpy (&(element->peer), &finger_trail[i], sizeof(struct GNUNET_PeerIdentity));
1567 GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->head, new_finger_entry->tail, element); 1710 GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->head, new_finger_entry->tail, element);
1568 i++; 1711 i++;
1712 }
1713 new_finger_entry->trail_length = trail_length;
1569 } 1714 }
1570 1715
1571 new_finger_entry->finger_map_index = finger_map_index;
1572 new_finger_entry->trail_length = trail_length;
1573
1574 /* FIXME: Here we are keeping multiple hashmap option so that there are 1716 /* FIXME: Here we are keeping multiple hashmap option so that there are
1575 multiple routes to reach to same finger, redundant routing. 1717 multiple routes to reach to same finger, redundant routing.
1576 * Also same peers could be our fingers for different finger map index */ 1718 * Also same peers could be our fingers for different finger map index
1719 * Should we handle the case where we have same fingers at the different
1720 * finger index but with different trail to reach. */
1577 GNUNET_assert (GNUNET_OK == 1721 GNUNET_assert (GNUNET_OK ==
1578 GNUNET_CONTAINER_multipeermap_put (finger_peermap, 1722 GNUNET_CONTAINER_multipeermap_put (finger_peermap,
1579 &(new_finger_entry->finger_identity), 1723 &(new_finger_entry->finger_identity),
1580 new_finger_entry, 1724 new_finger_entry,
1581 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); /* Fixme: change to multiple */ 1725 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); /* Fixme: change to multiple */
1582 1726 /* SUPU TEST CODE */
1727 /* Here I want to iterate over finger peer map, print its id and the trail
1728 to reach to the finger. */
1729 int test_index;
1730 struct GNUNET_CONTAINER_MultiPeerMapIterator *test_iter;
1731 struct FingerInfo *test_finger;
1732 test_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1733 FPRINTF (stderr,_("\nSUPU #### %s, %s, %d, size = %d####"),__FILE__, __func__,__LINE__,GNUNET_CONTAINER_multipeermap_size (finger_peermap));
1734 for (test_index = 0; test_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); test_index++)
1735 {
1736 FPRINTF (stderr,_("\nSUPU *********%s, %s, %d, %d entry*********"),__FILE__, __func__,__LINE__,test_index);
1737 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (test_iter, &key_ret,
1738 (const void **)&test_finger))
1739 {
1740 FPRINTF (stderr,_("\nSUPU %s, %s, %d "),__FILE__, __func__,__LINE__);
1741 struct GNUNET_PeerIdentity *print_peer;
1742 struct TrailPeerList *iterator;
1743 int z;
1744 iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
1745 print_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1746 memcpy (print_peer, &(test_finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
1747 FPRINTF (stderr,_("\nSUPU %s, %s, %d, finger_index = %d"), __FILE__, __func__,__LINE__,test_finger->finger_map_index);
1748 FPRINTF (stderr,_("\nSUPU %s, %s, %d, finger_identity = %s"),
1749 __FILE__, __func__,__LINE__, GNUNET_i2s (print_peer));
1750 iterator = test_finger->head;
1751 z = 0;
1752 while (z < test_finger->trail_length)
1753 {
1754 memcpy (print_peer, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
1755 FPRINTF (stderr,_("\nSUPU %s, %s, %d, trail[%d] = %s"),__FILE__, __func__,__LINE__,z,GNUNET_i2s (print_peer));
1756 z++;
1757 iterator = iterator->next;
1758 }
1759 }
1760 }
1761 FPRINTF (stderr,_("\nSUPU End of loop%s, %s, %d"),__FILE__, __func__,__LINE__);
1762 /* SUPU TEST CODE ENDS */
1763
1583 1764
1584 if (1 == GNUNET_CONTAINER_multipeermap_size (finger_peermap) 1765 if (1 == GNUNET_CONTAINER_multipeermap_size (finger_peermap)
1585 && (new_finger_entry->finger_map_index!= 1)) 1766 && (new_finger_entry->finger_map_index!= 1))
@@ -1774,13 +1955,12 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
1774 1955
1775 1956
1776/** 1957/**
1777 * FIXME:
1778 * 1. Do we have an expiration time for get request? Yes but I don't know its
1779 * use case and how to handle it
1780 * Send a get message to selected target friend. If target friend in NULL, 1958 * Send a get message to selected target friend. If target friend in NULL,
1781 * then search for a target friend. 1959 * then search for a target friend.
1782 * @param request_id Unique ID identifying this request 1960 * @param block_type type of the block
1783 * @param source_peer Peer which started get request 1961 * @param options routing options
1962 * @param desired_replication_level desired replication count
1963 * @param hop_count how many hops did this request traverse so far?
1784 * @param get_peer_path Peer list to reach to final destination which contains the data. 1964 * @param get_peer_path Peer list to reach to final destination which contains the data.
1785 * @param get_path_length Total numbers of peer in get_path 1965 * @param get_path_length Total numbers of peer in get_path
1786 * @param key Key key for the content 1966 * @param key Key key for the content
@@ -1789,12 +1969,16 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
1789 * @param current_dest_type Type of current destination can be either FRIEND or FINGER 1969 * @param current_dest_type Type of current destination can be either FRIEND or FINGER
1790 */ 1970 */
1791void 1971void
1792GDS_NEIGHBOURS_handle_get (struct GNUNET_PeerIdentity *source_peer, 1972GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type block_type,
1973 enum GNUNET_DHT_RouteOption options,
1974 uint32_t desired_replication_level,
1975 uint32_t hop_count,
1793 struct GNUNET_PeerIdentity *get_peer_path, 1976 struct GNUNET_PeerIdentity *get_peer_path,
1794 unsigned int get_path_length, 1977 unsigned int get_path_length,
1795 struct GNUNET_HashCode *key, 1978 struct GNUNET_HashCode *key,
1796 struct GNUNET_PeerIdentity *target_peer, 1979 struct GNUNET_PeerIdentity *target_peer,
1797 struct GNUNET_PeerIdentity *current_destination, 1980 struct GNUNET_PeerIdentity *current_destination,
1981 struct GNUNET_PeerIdentity *current_source,
1798 enum current_destination_type *current_dest_type) 1982 enum current_destination_type *current_dest_type)
1799{ 1983{
1800 struct PeerGetMessage *get_request; 1984 struct PeerGetMessage *get_request;
@@ -1818,32 +2002,33 @@ GDS_NEIGHBOURS_handle_get (struct GNUNET_PeerIdentity *source_peer,
1818 /* FIXME: Is this correct comparison? */ 2002 /* FIXME: Is this correct comparison? */
1819 if (NULL == target_peer) 2003 if (NULL == target_peer)
1820 { 2004 {
1821 /* This is the first call made from client file. */ 2005 /* We have received the request from the client file and we don't know
2006 to which peer should we forward the message to. */
1822 struct GNUNET_PeerIdentity *next_hop; 2007 struct GNUNET_PeerIdentity *next_hop;
1823 next_hop = find_successor (key_value, current_destination, current_dest_type); 2008 next_hop = find_successor (key_value, current_destination, current_dest_type);
1824 2009
1825 if (*current_dest_type == MY_ID) 2010 if (*current_dest_type == MY_ID)
1826 { 2011 {
1827 struct GNUNET_PeerIdentity *destination_peer;
1828 get_path = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2012 get_path = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1829 memcpy (get_path, &my_identity, sizeof (struct GNUNET_PeerIdentity)); 2013 memcpy (get_path, &my_identity, sizeof (struct GNUNET_PeerIdentity));
1830 get_path_length = 1; 2014 get_path_length = 1;
1831 destination_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2015 /* FIXME: At the moment I am just passing null,0 for values which I don't
1832 memcpy (destination_peer, source_peer, sizeof (struct GNUNET_PeerIdentity)); 2016 have. Also, handle return type. Modify this function and pass get path
1833 /* FIXME: We enter in this part of code only when this is our first 2017 and get path length and then in datacache_handle. here in this case
1834 call from client file. In client file we already have done datacache_get 2018 you can diretly call gds_client_handle_reply. */
1835 and if we already have the result. So, ideally code should never reach 2019#if 0
1836 here. Remove it after verifying. */ 2020 GDS_DATACACHE_handle_get (&(get_request->key),(get_request->block_type),
1837 /* FIXME: Call datacache_get but remove after verified above thing. */ 2021 get_path, get_path_length,get_path_length - 1,NULL);
1838 GDS_NEIGHBOURS_send_get_result (&my_identity,get_path, get_path_length, 2022#endif
1839 key,destination_peer, 0,
1840 NULL,0,NULL);
1841
1842 return; 2023 return;
1843 } 2024 }
1844 else 2025 else
1845 { 2026 {
1846 /* Find the friend corresponding to next_hop */ 2027 if (*current_dest_type == FINGER)
2028 {
2029 memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2030 }
2031
1847 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 2032 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
1848 } 2033 }
1849 } 2034 }
@@ -1852,16 +2037,16 @@ GDS_NEIGHBOURS_handle_get (struct GNUNET_PeerIdentity *source_peer,
1852 2037
1853 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 2038 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1854 pending->importance = 0; /* FIXME */ 2039 pending->importance = 0; /* FIXME */
1855 /* FIXME: Do we have an expiration time for get request */
1856 get_request = (struct PeerGetMessage *) &pending[1]; 2040 get_request = (struct PeerGetMessage *) &pending[1];
1857 pending->msg = &get_request->header; 2041 pending->msg = &get_request->header;
1858 get_request->header.size = htons (msize); 2042 get_request->header.size = htons (msize);
1859 get_request->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET); 2043 get_request->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET);
1860 get_request->get_path_length = htonl (get_path_length); 2044 get_request->get_path_length = htonl (get_path_length);
1861 get_request->key = *key; 2045 get_request->key = *key;
1862
1863 memcpy (&(get_request->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1864 memcpy (&(get_request->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity)); 2046 memcpy (&(get_request->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
2047 /* FIXME: Is this comparison correct? */
2048 if (current_source != NULL)
2049 memcpy (&(get_request->current_source), current_source, sizeof (struct GNUNET_PeerIdentity));
1865 get_request->current_dest_type = htonl (*current_dest_type); 2050 get_request->current_dest_type = htonl (*current_dest_type);
1866 get_path = (struct GNUNET_PeerIdentity *) &get_request[1]; 2051 get_path = (struct GNUNET_PeerIdentity *) &get_request[1];
1867 memcpy (get_path, get_peer_path, get_path_length * sizeof (struct GNUNET_PeerIdentity)); 2052 memcpy (get_path, get_peer_path, get_path_length * sizeof (struct GNUNET_PeerIdentity));
@@ -1873,13 +2058,45 @@ GDS_NEIGHBOURS_handle_get (struct GNUNET_PeerIdentity *source_peer,
1873 2058
1874 2059
1875/** 2060/**
1876 * FIXME: In this function, you just find the target friend and send the message 2061 * FIXME: Here you should update the fields of struct PeerGetResultMessage.
1877 * to next peer. In handle_dht_p2p_put, you should check the options and type 2062 * At the end of this message you should add the data and get path and send
1878 * and check if you are final destination or not. if not then find the next 2063 * to the original requesting client. and there you should call GDS_CLIENT_handle_reply
1879 * destination and send the message forward. 2064 * with correct parameter.
1880 * @param type type of the block 2065 * @param expiration
2066 * @param key
2067 * @param get_path_length
2068 * @param get_path
2069 * @param put_path_length
2070 * @param put_path
2071 * @param type
2072 * @param data_size
2073 * @param data
2074 */
2075void
2076GDS_NEIGHBOURS_datacache_get (struct GNUNET_TIME_Absolute expiration,
2077 const struct GNUNET_HashCode *key,
2078 unsigned int get_path_length,
2079 const struct GNUNET_PeerIdentity *get_path,
2080 unsigned int put_path_length,
2081 const struct GNUNET_PeerIdentity *put_path,
2082 enum GNUNET_BLOCK_Type type, size_t data_size,
2083 const void *data)
2084{
2085 /* Here you don't have the get path and get path length. you should call
2086 some function get those values and update the message and send them. */
2087}
2088
2089
2090/**
2091 * TODO: In case of put, you add the peer in the peer list in handle_dht_p2p_put.
2092 * Verify that the addition is correct and we are adding peers correctly and incrementing
2093 * the trail length correctly.
2094 * Handle a put request from client file. If I am the final destination,
2095 * do a put else forward the message to next peer.
2096 * @param block_type type of the block
1881 * @param options routing options 2097 * @param options routing options
1882 * @param desired_replication_level desired replication count 2098 * @param desired_replication_level desired replication count, 0 for current
2099 * implementation of X-Vine.
1883 * @param expiration_time when does the content expire 2100 * @param expiration_time when does the content expire
1884 * @param hop_count how many hops has this message traversed so far 2101 * @param hop_count how many hops has this message traversed so far
1885 * @param key key for the content 2102 * @param key key for the content
@@ -1887,12 +2104,13 @@ GDS_NEIGHBOURS_handle_get (struct GNUNET_PeerIdentity *source_peer,
1887 * @param put_path peers this request has traversed so far (if tracked) 2104 * @param put_path peers this request has traversed so far (if tracked)
1888 * @param data payload to store 2105 * @param data payload to store
1889 * @param data_size number of bytes in @a data 2106 * @param data_size number of bytes in @a data
1890 * @param current_destination 2107 * @param current_destination intermediate destination of the packet.
1891 * @param dest_type 2108 * @param current_source source for which @a current_destination is destination.
1892 * @param target_peer_id 2109 * @param dest_type type of @a current_destination.
2110 * @param target_peer_id Next peer to forward the message to.
1893 */ 2111 */
1894void 2112void
1895GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, 2113GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type block_type,
1896 enum GNUNET_DHT_RouteOption options, 2114 enum GNUNET_DHT_RouteOption options,
1897 uint32_t desired_replication_level, 2115 uint32_t desired_replication_level,
1898 struct GNUNET_TIME_Absolute expiration_time, 2116 struct GNUNET_TIME_Absolute expiration_time,
@@ -1902,6 +2120,7 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1902 struct GNUNET_PeerIdentity *put_path, 2120 struct GNUNET_PeerIdentity *put_path,
1903 const void *data, size_t data_size, 2121 const void *data, size_t data_size,
1904 struct GNUNET_PeerIdentity *current_destination, 2122 struct GNUNET_PeerIdentity *current_destination,
2123 struct GNUNET_PeerIdentity *current_source,
1905 enum current_destination_type dest_type, 2124 enum current_destination_type dest_type,
1906 struct GNUNET_PeerIdentity *target_peer) 2125 struct GNUNET_PeerIdentity *target_peer)
1907{ 2126{
@@ -1936,22 +2155,23 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1936 So, you need to search for the next peer to send this message to. */ 2155 So, you need to search for the next peer to send this message to. */
1937 struct GNUNET_PeerIdentity *next_hop; 2156 struct GNUNET_PeerIdentity *next_hop;
1938 2157
1939 next_hop = find_successor (key_value, current_dest, &dest_type); 2158 next_hop = find_successor (key_value, current_dest, &dest_type);
1940
1941
1942 if (dest_type == MY_ID) 2159 if (dest_type == MY_ID)
1943 { 2160 {
1944 /* FIXME: How do we handle different block types? */ 2161 /* FIXME: Choose one place to do datacache_put. I am doing put only if its
1945 /* FIXME: Here depending on the replication level choose 'r' successors 2162 destination so I will do no put operation
1946 to this peer and send put to all of these peers. */ 2163 in the client file.*/
1947 //replicate_put();
1948 GDS_DATACACHE_handle_put (expiration_time, key, put_path_length, put_path, 2164 GDS_DATACACHE_handle_put (expiration_time, key, put_path_length, put_path,
1949 type, data_size, data); 2165 block_type, data_size, data);
1950 return; 2166 return;
1951 } 2167 }
1952 else 2168 else
1953 { 2169 {
1954 /* Find the friend corresponding to next_hop */ 2170 /* Find the friend corresponding to next_hop */
2171 if (dest_type == FINGER)
2172 {
2173 memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2174 }
1955 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 2175 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
1956 } 2176 }
1957 } 2177 }
@@ -1966,11 +2186,19 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1966 ppm->header.size = htons (msize); 2186 ppm->header.size = htons (msize);
1967 ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT); 2187 ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT);
1968 ppm->options = htonl (options); 2188 ppm->options = htonl (options);
1969 ppm->type = htonl (type); 2189 ppm->block_type = htonl (block_type);
1970 ppm->hop_count = htonl (hop_count + 1); 2190 ppm->hop_count = htonl (hop_count + 1);
1971 ppm->desired_replication_level = htonl (desired_replication_level); 2191 ppm->desired_replication_level = htonl (desired_replication_level);
1972 ppm->put_path_length = htonl (put_path_length); 2192 ppm->put_path_length = htonl (put_path_length);
1973 ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time); 2193 ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
2194 /* FIXME: Here I am checking if we have a value in current_source then only copy.
2195 I am not sure if this checking is correct or not. */
2196 if (current_source != NULL)
2197 memcpy (&(ppm->current_source), current_source, sizeof (struct GNUNET_PeerIdentity));
2198
2199 /* FIXME: here current_destination is the parameter, current_dest is what you
2200 get when you call find_successor. names don't do justice to the function.
2201 Please change it*/
1974 if (current_destination != NULL) 2202 if (current_destination != NULL)
1975 memcpy (&(ppm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity)); 2203 memcpy (&(ppm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
1976 else 2204 else
@@ -1979,8 +2207,14 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1979 ppm->key = *key; 2207 ppm->key = *key;
1980 2208
1981 pp = (struct GNUNET_PeerIdentity *) &ppm[1]; 2209 pp = (struct GNUNET_PeerIdentity *) &ppm[1];
1982 memcpy (pp, put_path, 2210 /* FIXME: Is this comparison correct? Do we need this comparison. What happens
1983 sizeof (struct GNUNET_PeerIdentity) * put_path_length); 2211 in the case put_path_length is 0 and put_path is NULL, then at run time
2212 memcpy will fail. And I am not sure if comparing NULL is correct or not. */
2213 if (put_path_length != 0)
2214 {
2215 memcpy (pp, put_path,
2216 sizeof (struct GNUNET_PeerIdentity) * put_path_length);
2217 }
1984 memcpy (&pp[put_path_length], data, data_size); 2218 memcpy (&pp[put_path_length], data, data_size);
1985 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); 2219 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1986 target_friend->pending_count++; 2220 target_friend->pending_count++;
@@ -1989,29 +2223,36 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1989 2223
1990 2224
1991/** 2225/**
2226 * FIXME: I am removing source peer as the first element in the trail
2227 * is source identity.
2228 * If I am adding myself when I am source then I don't need destination
2229 * peer in get but if I am not adding then I need it. At the moment I am removing
2230 * it but will check later if its wrong.
1992 * Send get result back to requesting client. 2231 * Send get result back to requesting client.
1993 * @param source_peer 2232 * @param expiration when will the reply expire
2233 * @param key the query this reply is for
2234 * @param get_path_length number of peers in @a get_path
2235 * @param get_path path the reply took on get
2236 * @param put_path_length number of peers in @a put_path
2237 * @param put_path path the reply took on put
2238 * @param type type of the reply
2239 * @param data_size number of bytes in @a data
2240 * @param data application payload data
1994 * @param get_path 2241 * @param get_path
1995 * @param target_friend
1996 * @param get_path_length 2242 * @param get_path_length
1997 * @param key
1998 * @param destination_peer
1999 * @param current_path_index
2000 * @param data
2001 * @param data_size
2002 */ 2243 */
2003void 2244void
2004GDS_NEIGHBOURS_send_get_result (struct GNUNET_PeerIdentity *source_peer, 2245GDS_NEIGHBOURS_send_get_result (struct GNUNET_TIME_Absolute expiration,
2246 const struct GNUNET_HashCode *key,
2247 unsigned int put_path_length,
2248 const struct GNUNET_PeerIdentity *put_path,
2249 enum GNUNET_BLOCK_Type type, size_t data_size,
2250 const void *data,
2005 struct GNUNET_PeerIdentity *get_path, 2251 struct GNUNET_PeerIdentity *get_path,
2006 unsigned int get_path_length, 2252 unsigned int get_path_length,
2007 struct GNUNET_HashCode *key,
2008 struct GNUNET_PeerIdentity *destination_peer,
2009 unsigned int current_path_index, 2253 unsigned int current_path_index,
2010 const void *data, size_t data_size,
2011 struct GNUNET_PeerIdentity *next_hop) 2254 struct GNUNET_PeerIdentity *next_hop)
2012{ 2255{
2013 /* Add get_result into pending message and send the data to target friend.
2014 make a call GDS_CLIENTS_process_get_result() with all the fields. */
2015 struct PeerGetResultMessage *get_result; 2256 struct PeerGetResultMessage *get_result;
2016 struct GNUNET_PeerIdentity *get_result_path; 2257 struct GNUNET_PeerIdentity *get_result_path;
2017 struct P2PPendingMessage *pending; 2258 struct P2PPendingMessage *pending;
@@ -2026,7 +2267,9 @@ GDS_NEIGHBOURS_send_get_result (struct GNUNET_PeerIdentity *source_peer,
2026 GNUNET_break (0); 2267 GNUNET_break (0);
2027 return; 2268 return;
2028 } 2269 }
2029 2270 /* GET_REULT should have all the things which we want to pass in client_handle_reply
2271 put path put path length get path get length data data_size. and rest things
2272 are required to reach to the correct peer. */
2030 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 2273 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2031 pending->importance = 0; /* FIXME */ 2274 pending->importance = 0; /* FIXME */
2032 /* FIXME: Should we add an expiration time like in put message. */ 2275 /* FIXME: Should we add an expiration time like in put message. */
@@ -2034,8 +2277,6 @@ GDS_NEIGHBOURS_send_get_result (struct GNUNET_PeerIdentity *source_peer,
2034 pending->msg = &get_result->header; 2277 pending->msg = &get_result->header;
2035 get_result->header.size = htons (msize); 2278 get_result->header.size = htons (msize);
2036 get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT); 2279 get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT);
2037 memcpy (&(get_result->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
2038 memcpy (&(get_result->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
2039 get_result->current_path_index = current_path_index; 2280 get_result->current_path_index = current_path_index;
2040 get_result->key = *key; 2281 get_result->key = *key;
2041 2282
@@ -2066,8 +2307,8 @@ handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
2066 the requesting client and send back the result. */ 2307 the requesting client and send back the result. */
2067 struct PeerGetResultMessage *get_result; 2308 struct PeerGetResultMessage *get_result;
2068 struct GNUNET_PeerIdentity *get_path; 2309 struct GNUNET_PeerIdentity *get_path;
2069 void *payload; 2310 //void *payload;
2070 size_t payload_size; 2311 //size_t payload_size;
2071 size_t msize; 2312 size_t msize;
2072 unsigned int getlen; 2313 unsigned int getlen;
2073 int current_path_index; 2314 int current_path_index;
@@ -2092,10 +2333,11 @@ handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
2092 return GNUNET_YES; 2333 return GNUNET_YES;
2093 } 2334 }
2094 2335
2336 /* FIXME: Get the put_path */
2095 get_path = (struct GNUNET_PeerIdentity *) &get_result[1]; 2337 get_path = (struct GNUNET_PeerIdentity *) &get_result[1];
2096 payload = &get_path[getlen]; 2338 //payload = &get_path[getlen];
2097 payload_size = msize - (sizeof (struct PeerGetResultMessage) + 2339 /* payload_size = msize - (sizeof (struct PeerGetResultMessage) +
2098 getlen * sizeof (struct GNUNET_PeerIdentity)); 2340 getlen * sizeof (struct GNUNET_PeerIdentity));*/
2099 current_path_index = ntohl (get_result->current_path_index); 2341 current_path_index = ntohl (get_result->current_path_index);
2100 2342
2101 /* Here you just have to check if you are the destination or not if not 2343 /* Here you just have to check if you are the destination or not if not
@@ -2120,18 +2362,19 @@ handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
2120 2362
2121 if (current_path_index != 0) 2363 if (current_path_index != 0)
2122 current_path_index--; 2364 current_path_index--;
2123 2365#if 0
2124 GDS_NEIGHBOURS_send_get_result (&my_identity, get_path, 2366 GDS_NEIGHBOURS_send_get_result ((get_result->expiration), get_result->key,
2125 getlen,&(get_result->key),&(get_result->destination_peer), 2367 get_result->put_path_length, put_path,
2126 current_path_index, 2368 get_result->type, payload, payload_size
2127 payload, payload_size, next_hop); 2369 get_path, getlen,current_path_index,
2370 next_hop);
2371#endif
2128 return GNUNET_YES; 2372 return GNUNET_YES;
2129 } 2373 }
2130 return GNUNET_SYSERR; 2374 return GNUNET_SYSERR;
2131} 2375}
2132 2376
2133 2377
2134
2135/** 2378/**
2136 * Core handler for p2p put requests. 2379 * Core handler for p2p put requests.
2137 * 2380 *
@@ -2151,7 +2394,6 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
2151 enum GNUNET_DHT_RouteOption options; 2394 enum GNUNET_DHT_RouteOption options;
2152 enum current_destination_type current_dst_type; 2395 enum current_destination_type current_dst_type;
2153 struct GNUNET_PeerIdentity *current_destination; 2396 struct GNUNET_PeerIdentity *current_destination;
2154 struct GNUNET_PeerIdentity *source_peer;
2155 struct GNUNET_PeerIdentity *next_hop; 2397 struct GNUNET_PeerIdentity *next_hop;
2156 struct GNUNET_HashCode test_key; 2398 struct GNUNET_HashCode test_key;
2157 uint64_t key_value; 2399 uint64_t key_value;
@@ -2180,36 +2422,33 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
2180 payload_size = msize - (sizeof (struct PeerPutMessage) + 2422 payload_size = msize - (sizeof (struct PeerPutMessage) +
2181 putlen * sizeof (struct GNUNET_PeerIdentity)); 2423 putlen * sizeof (struct GNUNET_PeerIdentity));
2182 2424
2183 /* FIXME: I don't understand what exactly are we doing here. */ 2425 switch (GNUNET_BLOCK_get_key (GDS_block_context, ntohl (put->block_type),
2184 switch (GNUNET_BLOCK_get_key 2426 payload, payload_size, &test_key))
2185 (GDS_block_context, ntohl (put->type), payload, payload_size,
2186 &test_key))
2187 { 2427 {
2188 case GNUNET_YES: 2428 case GNUNET_YES:
2189 if (0 != memcmp (&test_key, &put->key, sizeof (struct GNUNET_HashCode))) 2429 if (0 != memcmp (&test_key, &put->key, sizeof (struct GNUNET_HashCode)))
2190 { 2430 {
2191 char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key)); 2431 char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key));
2432 GNUNET_break_op (0);
2433 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2434 "PUT with key `%s' for block with key %s\n",
2435 put_s, GNUNET_h2s_full (&test_key));
2436 GNUNET_free (put_s);
2437 return GNUNET_YES;
2438 }
2439 break;
2440 case GNUNET_NO:
2192 GNUNET_break_op (0); 2441 GNUNET_break_op (0);
2193 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2194 "PUT with key `%s' for block with key %s\n",
2195 put_s, GNUNET_h2s_full (&test_key));
2196 GNUNET_free (put_s);
2197 return GNUNET_YES; 2442 return GNUNET_YES;
2198 } 2443 case GNUNET_SYSERR:
2199 break; 2444 /* cannot verify, good luck */
2200 case GNUNET_NO: 2445 break;
2201 GNUNET_break_op (0);
2202 return GNUNET_YES;
2203 case GNUNET_SYSERR:
2204 /* cannot verify, good luck */
2205 break;
2206 } 2446 }
2207 2447
2208 /* FIXME: This part is also not clear to me.*/ 2448 if (ntohl (put->block_type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for all tpyes */
2209 if (ntohl (put->type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for all tpyes */
2210 { 2449 {
2211 switch (GNUNET_BLOCK_evaluate (GDS_block_context, 2450 switch (GNUNET_BLOCK_evaluate (GDS_block_context,
2212 ntohl (put->type), 2451 ntohl (put->block_type),
2213 NULL, /* query */ 2452 NULL, /* query */
2214 NULL, 0, /* bloom filer */ 2453 NULL, 0, /* bloom filer */
2215 NULL, 0, /* xquery */ 2454 NULL, 0, /* xquery */
@@ -2243,54 +2482,73 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
2243 else 2482 else
2244 putlen = 0; 2483 putlen = 0;
2245 2484
2246 /* Copy the fields of message, call find successor or gds_routing_search,
2247 depending on the destination_type and if you are the final destination,
2248 do a datache put or if option is. else call gds_neighbours_handle_get with
2249 correct parameters. */
2250 current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2485 current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2251 memcpy (current_destination, &(put->current_destination), sizeof (struct GNUNET_PeerIdentity)); 2486 memcpy (current_destination, &(put->current_destination), sizeof (struct GNUNET_PeerIdentity));
2252 current_dst_type = ntohl (put->current_destination_type); 2487 current_dst_type = ntohl (put->current_destination_type);
2253 memcpy (&key_value, &(put->key), sizeof (uint64_t)); 2488 memcpy (&key_value, &(put->key), sizeof (uint64_t));
2254 source_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2255 memcpy (source_peer, &(put->source_peer), sizeof (struct GNUNET_PeerIdentity));
2256 2489
2257 if (current_dst_type == FRIEND) 2490 if (current_dst_type == FRIEND)
2258 { 2491 {
2259 next_hop = find_successor (key_value, current_destination, &current_dst_type); 2492 next_hop = find_successor (key_value, current_destination, &current_dst_type);
2260 } 2493 }
2261 else if (current_dst_type == FINGER) 2494 else if (current_dst_type == FINGER)
2262 { 2495 {
2263 next_hop = GDS_ROUTING_search (source_peer, current_destination, peer); 2496 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, current_destination))
2264 } 2497 {
2265 2498 next_hop = find_successor (key_value, current_destination, &current_dst_type);
2266 if (current_dst_type == MY_ID) 2499 }
2267 { 2500 else
2268 /* Here datacache_put*/ 2501 {
2269 /* FIXME: Here depending on replication, call replicate_put() to do the 2502 next_hop = GDS_ROUTING_search (&(put->current_source), current_destination, peer);
2270 put operation on 'r' successors. */ 2503 current_dst_type = FRIEND;
2271 GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time), 2504 }
2272 &(put->key),putlen, pp, ntohl (put->type), payload_size, 2505 }
2273 payload); 2506
2274 return GNUNET_YES; 2507 if (current_dst_type == MY_ID)
2275 } 2508 {
2276 else 2509 GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time),
2277 { 2510 &(put->key),putlen, pp, ntohl (put->block_type),
2278 /* here call gds_neighbours*/ 2511 payload_size, payload);
2279 GDS_NEIGHBOURS_handle_put (ntohl (put->type),ntohl (put->options), 2512 return GNUNET_YES;
2280 ntohl (put->desired_replication_level), 2513 }
2281 GNUNET_TIME_absolute_ntoh (put->expiration_time), 2514 else
2282 ntohl (put->hop_count),&put->key, putlen, 2515 {
2283 pp, payload, payload_size, 2516 struct GNUNET_PeerIdentity *current_source;
2284 current_destination, current_dst_type, next_hop); 2517 if (current_dst_type == FINGER)
2285 return GNUNET_YES; 2518 {
2286 } 2519 current_source = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2520 memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2521 }
2522 else
2523 current_source = NULL;
2524
2525 GDS_CLIENTS_process_put (options,
2526 ntohl (put->block_type),
2527 ntohl (put->hop_count),
2528 ntohl (put->desired_replication_level),
2529 putlen, pp,
2530 GNUNET_TIME_absolute_ntoh (put->expiration_time),
2531 &put->key,
2532 payload,
2533 payload_size);
2534
2535 GDS_NEIGHBOURS_handle_put (ntohl (put->block_type),ntohl (put->options),
2536 ntohl (put->desired_replication_level),
2537 GNUNET_TIME_absolute_ntoh (put->expiration_time),
2538 ntohl (put->hop_count),&put->key, putlen,
2539 pp, payload, payload_size,
2540 current_destination, current_source,current_dst_type, next_hop);
2541 return GNUNET_YES;
2542 }
2287 return GNUNET_SYSERR; 2543 return GNUNET_SYSERR;
2288} 2544}
2289 2545
2290 2546
2291/** 2547/**
2292 * FIXME: Handle expiration, options, block type, replication 2548 * FIXME
2293 * referring the old code. 2549 * 1. I don't do block evalute as it uses xquery and bf for evaluation.Is
2550 * it okay if I just pass NULL. I am anyways going to pass NULL in case of
2551 * datacache_get?
2294 * Core handler for p2p get requests. 2552 * Core handler for p2p get requests.
2295 * 2553 *
2296 * @param cls closure 2554 * @param cls closure
@@ -2306,9 +2564,11 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
2306 struct PeerGetMessage *get; 2564 struct PeerGetMessage *get;
2307 struct GNUNET_PeerIdentity *current_destination; 2565 struct GNUNET_PeerIdentity *current_destination;
2308 uint64_t key_value; 2566 uint64_t key_value;
2309 enum current_destination_type cuurent_dest_type; 2567 enum current_destination_type current_dest_type;
2310 struct GNUNET_PeerIdentity *next_hop; 2568 struct GNUNET_PeerIdentity *next_hop;
2311 struct GNUNET_PeerIdentity *get_path; 2569 struct GNUNET_PeerIdentity *get_path;
2570 enum GNUNET_BLOCK_Type block_type;
2571 enum GNUNET_DHT_RouteOption options;
2312 size_t msize; 2572 size_t msize;
2313 unsigned int get_length; 2573 unsigned int get_length;
2314 2574
@@ -2333,52 +2593,70 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
2333 return GNUNET_YES; 2593 return GNUNET_YES;
2334 } 2594 }
2335 2595
2336 get = (struct PeerGetMessage *) message;
2337 current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2596 current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2338 memcpy (current_destination, &(get->current_destination), sizeof (struct GNUNET_PeerIdentity)); 2597 memcpy (current_destination, &(get->current_destination), sizeof (struct GNUNET_PeerIdentity));
2339 memcpy (&key_value, &(get->key), sizeof (uint64_t)); 2598 memcpy (&key_value, &(get->key), sizeof (uint64_t));
2340 cuurent_dest_type = ntohl (get->current_dest_type); 2599 current_dest_type = ntohl (get->current_dest_type);
2600 block_type = ntohl (get->block_type);
2601 options = ntohl (get->options);
2341 2602
2342 if (cuurent_dest_type == FRIEND) 2603 if (current_dest_type == FRIEND)
2343 {
2344 next_hop = find_successor (key_value, current_destination, &cuurent_dest_type);
2345 }
2346 else if (cuurent_dest_type == FINGER)
2347 { 2604 {
2348 next_hop = GDS_ROUTING_search (&(get->source_peer), current_destination, peer); 2605 next_hop = find_successor (key_value, current_destination, &current_dest_type);
2349 } 2606 }
2350 2607 else if (current_dest_type == FINGER)
2351 if (cuurent_dest_type == MY_ID)
2352 { 2608 {
2353 struct GNUNET_PeerIdentity *destination_peer; 2609 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, current_destination))
2354 //struct GNUNET_PeerIdentity *next_hop; 2610 {
2355 //int current_path_index; 2611 next_hop = find_successor (key_value, current_destination, &current_dest_type);
2356 2612 }
2357 /* Add yourself to the get path, increment the get length. */ 2613 else
2358 destination_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2614 {
2359 memcpy (destination_peer, &(get->source_peer), sizeof (struct GNUNET_PeerIdentity)); 2615 next_hop = GDS_ROUTING_search (&(get->current_source), current_destination, peer);
2360 //current_path_index = get_length - 1; 2616 current_dest_type = FRIEND;
2361 2617 }
2362 /* I am the final destination. Call GDS_NEIGHBOURS_send_get_result. 2618 }
2363 * FIXME: Last parameters are data and data size. First implement datacache get 2619
2364 * and get the result and send the data. Also seach for the next friend to pass 2620 /* Add sender to get path */
2365 * this message to. */ 2621 struct GNUNET_PeerIdentity gp[get_length + 1];
2366#if 0 2622 memcpy (gp, get_path, get_length * sizeof (struct GNUNET_PeerIdentity));
2367 /* FIXME: Here we should call GDS_CLIENT_handle_reply. */ 2623 gp[get_length + 1] = *peer;
2368 GDS_NEIGHBOURS_send_get_result (get->request_id, &my_identity, get_path, 2624 get_length = get_length + 1;
2369 get_length,&(get->key), destination_peer, current_path_index, 2625
2370 NULL, 0, next_hop); 2626 if (current_dest_type == MY_ID)
2371#endif 2627 {
2628 struct GNUNET_PeerIdentity final_get_path[get_length+1];
2629 memcpy (final_get_path, get_path, get_length * sizeof (struct GNUNET_PeerIdentity));
2630 memcpy (final_get_path, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2631 get_length = get_length + 1;
2632 struct GNUNET_PeerIdentity *next_hop;
2633 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2634 /* FIXME: Check if we need to have a check on get length. */
2635 memcpy (next_hop, &final_get_path[get_length-2], sizeof (struct GNUNET_PeerIdentity));
2636#if 0
2637 GDS_DATACACHE_handle_get (&(get->key),(get->block_type),
2638 final_get_path, get_length,get_length - 1,next_hop);
2639#endif
2372 return GNUNET_YES; 2640 return GNUNET_YES;
2373 } 2641 }
2374 else 2642 else
2375 { 2643 {
2376 /* FIXME: Add your self to the get path and increment the get length. */ 2644 struct GNUNET_PeerIdentity *current_source;
2645 current_source = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2646 if (current_dest_type == FINGER)
2647 {
2648 memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2649 }
2650 else
2651 /* FIXME: Is this correct? */
2652 {
2653 /* how to handle the case when we don't have any value for current source.*/
2654 }
2377 2655
2378 /* FIXME: Does it matter if the dest_type is friend or finger. */ 2656 GDS_NEIGHBOURS_handle_get (block_type, options, get->desired_replication_level,
2379 GDS_NEIGHBOURS_handle_get (&(get->source_peer), get_path, 2657 get->hop_count, gp,
2380 get_length, &(get->key),next_hop, 2658 get_length, &(get->key),next_hop,
2381 current_destination,&cuurent_dest_type); 2659 current_destination, &(get->current_source),&current_dest_type);
2382 2660
2383 return GNUNET_YES; 2661 return GNUNET_YES;
2384 } 2662 }
@@ -2386,6 +2664,57 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
2386} 2664}
2387 2665
2388 2666
2667
2668/**
2669 * Send tral rejection message
2670 * @param source_peer Source peer which wants to set up the trail.
2671 * @param finger_identity Finger identity to which it want to setup the trail.
2672 * @param congested_peer Peer which has send trail rejection message
2673 * @param next_hop Peer to which this message should be forwarded.
2674 * @param finger_map_index
2675 * @param trail_peer_list
2676 * @param trail_length
2677 */
2678void
2679GDS_NEIGHBOURS_send_trail_rejection_message(struct GNUNET_PeerIdentity *source_peer,
2680 uint64_t finger_identity,
2681 struct GNUNET_PeerIdentity *congested_peer,
2682 const struct GNUNET_PeerIdentity *next_hop,
2683 unsigned int finger_map_index,
2684 struct GNUNET_PeerIdentity *trail_peer_list,
2685 unsigned int trail_length)
2686{
2687 struct PeerTrailRejectionMessage *trail_rejection;
2688 struct GNUNET_PeerIdentity *trail_list;
2689 struct P2PPendingMessage *pending;
2690 struct FriendInfo *target_friend;
2691 size_t msize;
2692
2693 msize = sizeof (struct PeerTrailRejectionMessage);
2694
2695 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2696 pending->importance = 0; /* FIXME */
2697 pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
2698 trail_rejection = (struct PeerTrailRejectionMessage *) &pending[1];
2699 pending->msg = &trail_rejection->header;
2700 trail_rejection->header.size = htons (msize);
2701 trail_rejection->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
2702 memcpy (&(trail_rejection->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
2703 memcpy (&(trail_rejection->congested_peer), congested_peer, sizeof (struct GNUNET_PeerIdentity));
2704 memcpy (&(trail_rejection->finger_identity), &finger_identity, sizeof (uint64_t));
2705 trail_rejection->finger_map_index = htonl(finger_map_index);
2706 trail_rejection->trail_length = htonl (trail_length);
2707
2708 trail_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
2709 memcpy (trail_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2710
2711 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2712 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2713 target_friend->pending_count++;
2714 process_friend_queue (target_friend);
2715}
2716
2717
2389/** 2718/**
2390 * Handle a PeerTrailSetupMessage. 2719 * Handle a PeerTrailSetupMessage.
2391 * @param cls closure 2720 * @param cls closure
@@ -2436,6 +2765,20 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
2436 current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2765 current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2437 memcpy (current_destination, &(trail_setup->current_destination), sizeof (struct GNUNET_PeerIdentity)); 2766 memcpy (current_destination, &(trail_setup->current_destination), sizeof (struct GNUNET_PeerIdentity));
2438 2767
2768 /* TODO:
2769 each peer maintains a list of trail fail list. there it stores an entry with
2770 source, finger identity it was trying, hop which rejected. it again call
2771 select_random_friend but does not consider me. and starts trail setup
2772 again. */
2773 if (GDS_ROUTING_size() > 1)
2774 {
2775 /* Setup the trail rejection message and send the message to peer. */
2776 /* FIXME: you need to pass the trail, trail length and finger map index. */
2777 GDS_NEIGHBOURS_send_trail_rejection_message (&(trail_setup->source_peer),
2778 trail_setup->destination_finger,
2779 &my_identity, peer, finger_map_index,
2780 trail_peer_list, trail_length);
2781 }
2439 /* Find the next hop to send the packet to. */ 2782 /* Find the next hop to send the packet to. */
2440 if (current_dest_type == FRIEND) 2783 if (current_dest_type == FRIEND)
2441 { 2784 {
@@ -2452,7 +2795,7 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
2452 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_setup->current_destination), 2795 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_setup->current_destination),
2453 &my_identity))) 2796 &my_identity)))
2454 { 2797 {
2455 next_hop = GDS_ROUTING_search (&(trail_setup->source_peer), 2798 next_hop = GDS_ROUTING_search (&(trail_setup->current_source),
2456 &(trail_setup->current_destination), peer); 2799 &(trail_setup->current_destination), peer);
2457 /* As an optimization, find the successor from the find successor and 2800 /* As an optimization, find the successor from the find successor and
2458 compare both the ids to find the closest peer. */ 2801 compare both the ids to find the closest peer. */
@@ -2509,37 +2852,28 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
2509 2852
2510 return GNUNET_YES; 2853 return GNUNET_YES;
2511 } 2854 }
2512 else if (next_hop == NULL)
2513 {
2514 return GNUNET_SYSERR;
2515 }
2516 else 2855 else
2517 { 2856 {
2518 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 2857 struct GNUNET_PeerIdentity *current_source;
2519 if(current_dest_type == FINGER) 2858 current_source = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2859 if (current_dest_type == FINGER)
2520 { 2860 {
2521 /* FIXME: Here it can even return err if routing entries have crossed the 2861 memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2522 threshold. In such a case, you should send back a trail setup fail message
2523 to node just before your. THen its the responsiblity of node before you
2524 to find an alternate path to reach to the current_desintation which doesnot
2525 involve you.*/
2526
2527 if ( GNUNET_SYSERR == GDS_ROUTING_add (&(trail_setup->source_peer),
2528 &(trail_setup->current_destination),
2529 next_hop, peer))
2530 {
2531 //trail_setup_rejection()--> add to a list of fail trails and start
2532 // a new search rejecting this peer.
2533 }
2534 } 2862 }
2535 2863 else
2864 current_source = NULL;
2865
2866 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2867 /* FiXME: Is it correct to use null value for current source. */
2536 GDS_NEIGHBOURS_send_trail_setup (&(trail_setup->source_peer), 2868 GDS_NEIGHBOURS_send_trail_setup (&(trail_setup->source_peer),
2537 trail_setup->destination_finger, 2869 trail_setup->destination_finger,
2538 current_destination, target_friend, trail_length, 2870 current_destination,current_source,
2539 peer_list, finger_map_index, current_dest_type); 2871 target_friend, trail_length, peer_list,
2872 finger_map_index, current_dest_type);
2540 2873
2541 return GNUNET_YES; 2874 return GNUNET_YES;
2542 } 2875 }
2876
2543 return GNUNET_SYSERR; 2877 return GNUNET_SYSERR;
2544} 2878}
2545 2879
@@ -2592,25 +2926,11 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
2592 if ( 0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer), 2926 if ( 0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
2593 &my_identity))) 2927 &my_identity)))
2594 { 2928 {
2595#if 0
2596 /* I don't remember why I have written this code. */
2597 if (finger_map_index == 1)
2598 {
2599 struct GNUNET_PeerIdentity *new_trail_list;
2600 new_trail_list = invert_trail_list (&(trail_result->finger_identity),
2601 trail_peer_list, trail_length);
2602 finger_table_add (&(trail_result->finger_identity), new_trail_list, trail_length,
2603 finger_map_index);
2604 return GNUNET_YES;
2605 }
2606 else
2607 {
2608#endif
2609 finger_table_add (&(trail_result->finger_identity), trail_peer_list, trail_length, 2929 finger_table_add (&(trail_result->finger_identity), trail_peer_list, trail_length,
2610 finger_map_index); 2930 finger_map_index);
2611 2931
2612 return GNUNET_YES; 2932 return GNUNET_YES;
2613 //} 2933
2614 } 2934 }
2615 else 2935 else
2616 { 2936 {
@@ -2625,7 +2945,13 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
2625 { 2945 {
2626 memcpy (next_hop, &(trail_peer_list[current_trail_index-1]),sizeof (struct GNUNET_PeerIdentity)); 2946 memcpy (next_hop, &(trail_peer_list[current_trail_index-1]),sizeof (struct GNUNET_PeerIdentity));
2627 } 2947 }
2628 2948
2949
2950 /* If trail length = 2, it means that destination and source peer are friends
2951 Then don't add an entry. */
2952 if (trail_length != 2)
2953 GDS_ROUTING_add (&(trail_result->destination_peer), &(trail_result->finger_identity),
2954 peer, next_hop);
2629 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 2955 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2630 GNUNET_free (next_hop); 2956 GNUNET_free (next_hop);
2631 2957
@@ -2936,6 +3262,64 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti
2936 3262
2937 3263
2938/** 3264/**
3265 * FIXME: Does it matter if the packet was going to a finger or friend?
3266 * Core handle for p2p trail rejection messages.
3267 * @param cls closure
3268 * @param message message
3269 * @param peer peer identity this notification is about
3270 * @return GNUNET_OK on success, GNUNET_SYSERR on error
3271 */
3272static
3273int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *peer,
3274 const struct GNUNET_MessageHeader *message)
3275{
3276 struct PeerTrailRejectionMessage *trail_rejection;
3277 struct FailedTrail *trail_fail;
3278 struct FriendInfo *target_friend;
3279 struct GNUNET_PeerIdentity *trail_peer_list;
3280 unsigned int finger_map_index;
3281 size_t msize;
3282
3283 msize = ntohs (message->size);
3284 if (msize < sizeof (struct PeerTrailRejectionMessage))
3285 {
3286 GNUNET_break_op (0);
3287 return GNUNET_YES;
3288 }
3289
3290 trail_rejection = (struct PeerTrailRejectionMessage *) message;
3291 trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
3292 finger_map_index = ntohl (trail_rejection->finger_map_index);
3293 trail_fail = GNUNET_malloc (sizeof (struct FailedTrail));
3294 memcpy (&(trail_fail->source_peer), &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity));
3295 memcpy (&(trail_fail->congested_peer), &(trail_rejection->congested_peer), sizeof (struct GNUNET_PeerIdentity));
3296 memcpy (&(trail_fail->destination_finger_value), &(trail_rejection->finger_identity), sizeof (uint64_t));
3297
3298 GNUNET_assert (GNUNET_OK ==
3299 GNUNET_CONTAINER_multipeermap_put (failed_trail_list, &(trail_fail->source_peer),
3300 trail_fail, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
3301
3302 /* FIXME: Is it okay if I pass the struct as parameter. */
3303 target_friend = select_random_friend (&(trail_fail->congested_peer));
3304
3305 if(NULL != target_friend)
3306 {
3307 /* FIXME: Here I am passing NULL for current source, is it correct?
3308 also, we set the current source only if current_destination_type
3309 is finger. */
3310 GDS_NEIGHBOURS_send_trail_setup (&(trail_fail->source_peer),
3311 trail_fail->destination_finger_value,
3312 &(target_friend->id),
3313 NULL, target_friend, ntohl (trail_rejection->trail_length),
3314 trail_peer_list,
3315 finger_map_index, FRIEND);
3316 return GNUNET_YES;
3317 }
3318 return GNUNET_SYSERR;
3319}
3320
3321
3322/**
2939 * Initialize neighbours subsystem. 3323 * Initialize neighbours subsystem.
2940 * @return GNUNET_OK on success, GNUNET_SYSERR on error 3324 * @return GNUNET_OK on success, GNUNET_SYSERR on error
2941 */ 3325 */
@@ -2951,6 +3335,7 @@ GDS_NEIGHBOURS_init()
2951 {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR, 0}, 3335 {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR, 0},
2952 {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0}, 3336 {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0},
2953 {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0}, 3337 {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0},
3338 {&handle_dht_p2p_trail_rejection, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION, 0},
2954 {NULL, 0, 0} 3339 {NULL, 0, 0}
2955 }; 3340 };
2956 3341
@@ -2962,8 +3347,9 @@ GDS_NEIGHBOURS_init()
2962 return GNUNET_SYSERR; 3347 return GNUNET_SYSERR;
2963 3348
2964 friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO); 3349 friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
2965 finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS, GNUNET_NO); 3350 finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS, GNUNET_NO);
2966 3351 /* FIXME: Not sure if this value is correct for this data structure. */
3352 failed_trail_list = GNUNET_CONTAINER_multipeermap_create (LINK_THRESHOLD, GNUNET_NO);
2967 return GNUNET_OK; 3353 return GNUNET_OK;
2968} 3354}
2969 3355
diff --git a/src/dht/gnunet-service-xdht_neighbours.h b/src/dht/gnunet-service-xdht_neighbours.h
index 8e0fce225..e8809d11a 100644
--- a/src/dht/gnunet-service-xdht_neighbours.h
+++ b/src/dht/gnunet-service-xdht_neighbours.h
@@ -73,6 +73,7 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
73 struct GNUNET_PeerIdentity *put_path, 73 struct GNUNET_PeerIdentity *put_path,
74 const void *data, size_t data_size, 74 const void *data, size_t data_size,
75 struct GNUNET_PeerIdentity *current_destination, 75 struct GNUNET_PeerIdentity *current_destination,
76 struct GNUNET_PeerIdentity *current_source,
76 enum current_destination_type dest_type, 77 enum current_destination_type dest_type,
77 struct GNUNET_PeerIdentity *target_peer_id); 78 struct GNUNET_PeerIdentity *target_peer_id);
78 79
@@ -85,34 +86,71 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
85 * @param key 86 * @param key
86 */ 87 */
87void 88void
88GDS_NEIGHBOURS_handle_get (struct GNUNET_PeerIdentity *source_peer, 89GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type block_type,
89 struct GNUNET_PeerIdentity *get_path, 90 enum GNUNET_DHT_RouteOption options,
91 uint32_t desired_replication_level,
92 uint32_t hop_count,
93 struct GNUNET_PeerIdentity *get_peer_path,
90 unsigned int get_path_length, 94 unsigned int get_path_length,
91 struct GNUNET_HashCode *key, 95 struct GNUNET_HashCode *key,
92 struct GNUNET_PeerIdentity *target_peer, 96 struct GNUNET_PeerIdentity *target_peer,
93 struct GNUNET_PeerIdentity *current_destination, 97 struct GNUNET_PeerIdentity *current_destination,
94 enum current_destination_type *type); 98 struct GNUNET_PeerIdentity *current_source,
99 enum current_destination_type *current_dest_type);
100
95 101
96/** 102/**
97 * Send get result back to requesting client. 103 * FIXME: I am removing source peer as the first element in the trail
98 * @param source_peer 104 * is source identity.
105 * Send get result back to requesting client.
106 * @param expiration when will the reply expire
107 * @param key the query this reply is for
108 * @param get_path_length number of peers in @a get_path
109 * @param get_path path the reply took on get
110 * @param put_path_length number of peers in @a put_path
111 * @param put_path path the reply took on put
112 * @param type type of the reply
113 * @param data_size number of bytes in @a data
114 * @param data application payload data
99 * @param get_path 115 * @param get_path
100 * @param get_path_length 116 * @param get_path_length
101 * @param key
102 * @param destination_peer
103 * @param current_path_index
104 * @param data
105 * @param data_size
106 */ 117 */
107void 118void
108GDS_NEIGHBOURS_send_get_result (struct GNUNET_PeerIdentity *source_peer, 119GDS_NEIGHBOURS_send_get_result (struct GNUNET_TIME_Absolute expiration,
120 const struct GNUNET_HashCode *key,
121 unsigned int put_path_length,
122 const struct GNUNET_PeerIdentity *put_path,
123 enum GNUNET_BLOCK_Type type, size_t data_size,
124 const void *data,
109 struct GNUNET_PeerIdentity *get_path, 125 struct GNUNET_PeerIdentity *get_path,
110 unsigned int get_path_length, 126 unsigned int get_path_length,
111 struct GNUNET_HashCode *key, 127 unsigned int current_trail_index,
112 struct GNUNET_PeerIdentity *destination_peer, 128 struct GNUNET_PeerIdentity *next_hop);
113 unsigned int current_path_index, 129
114 const void *data, size_t data_size, 130/**
115 struct GNUNET_PeerIdentity *next_peer); 131 * FIXME: Here you should update the fields of struct PeerGetResultMessage.
132 * At the end of this message you should add the data and get path and send
133 * to the original requesting client. and there you should call GDS_CLIENT_handle_reply
134 * with correct parameter.
135 * @param expiration
136 * @param key
137 * @param get_path_length
138 * @param get_path
139 * @param put_path_length
140 * @param put_path
141 * @param type
142 * @param data_size
143 * @param data
144 */
145void
146GDS_NEIGHBOURS_datacache_get (struct GNUNET_TIME_Absolute expiration,
147 const struct GNUNET_HashCode *key,
148 unsigned int get_path_length,
149 const struct GNUNET_PeerIdentity *get_path,
150 unsigned int put_path_length,
151 const struct GNUNET_PeerIdentity *put_path,
152 enum GNUNET_BLOCK_Type type, size_t data_size,
153 const void *data);
116 154
117 155
118/** 156/**
diff --git a/src/dht/gnunet-service-xdht_routing.c b/src/dht/gnunet-service-xdht_routing.c
index f7e56c115..f083b6e62 100644
--- a/src/dht/gnunet-service-xdht_routing.c
+++ b/src/dht/gnunet-service-xdht_routing.c
@@ -84,8 +84,8 @@ static struct GNUNET_CONTAINER_MultiPeerMap *routing_table;
84int 84int
85GDS_ROUTING_add (struct GNUNET_PeerIdentity *source, 85GDS_ROUTING_add (struct GNUNET_PeerIdentity *source,
86 struct GNUNET_PeerIdentity *dest, 86 struct GNUNET_PeerIdentity *dest,
87 struct GNUNET_PeerIdentity *next_hop, 87 const struct GNUNET_PeerIdentity *next_hop,
88 const struct GNUNET_PeerIdentity *prev_hop) 88 struct GNUNET_PeerIdentity *prev_hop)
89{ 89{
90 struct RoutingTrail *new_routing_entry; 90 struct RoutingTrail *new_routing_entry;
91 91
@@ -102,6 +102,33 @@ GDS_ROUTING_add (struct GNUNET_PeerIdentity *source,
102 GNUNET_CONTAINER_multipeermap_put (routing_table, 102 GNUNET_CONTAINER_multipeermap_put (routing_table,
103 dest, new_routing_entry, 103 dest, new_routing_entry,
104 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 104 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
105
106 /* SUPU TEST CODE */
107 /* Here I want to see if routing table is correct or not. */
108 int test_index;
109 struct GNUNET_CONTAINER_MultiPeerMapIterator *test_iter;
110 struct GNUNET_PeerIdentity *print_peer;
111 print_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
112 struct RoutingTrail *test_trail;
113 test_iter = GNUNET_CONTAINER_multipeermap_iterator_create (routing_table);
114 for (test_index = 0; test_index < GNUNET_CONTAINER_multipeermap_size (routing_table); test_index++)
115 {
116 FPRINTF (stderr,_("\nSUPU %s, %s, %d, entry[%d]"),__FILE__, __func__,__LINE__,test_index);
117 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (test_iter, NULL,
118 (const void **)&test_trail))
119 {
120 memcpy (print_peer, &(test_trail->source),sizeof (struct GNUNET_PeerIdentity));
121 FPRINTF (stderr,_("\nSUPU %s, %s, %d, test_trail->source =%s"),__FILE__, __func__,__LINE__,GNUNET_i2s (print_peer));
122 memcpy (print_peer, &(test_trail->destination),sizeof (struct GNUNET_PeerIdentity));
123 FPRINTF (stderr,_("\nSUPU %s, %s, %d, test_trail->destination =%s"),__FILE__, __func__,__LINE__,GNUNET_i2s(print_peer));
124 memcpy (print_peer, &(test_trail->prev_hop),sizeof (struct GNUNET_PeerIdentity));
125 FPRINTF (stderr,_("\nSUPU %s, %s, %d, test_trail->prev_hop =%s"),__FILE__, __func__,__LINE__,GNUNET_i2s(print_peer));
126 memcpy (print_peer, &(test_trail->next_hop),sizeof (struct GNUNET_PeerIdentity));
127 FPRINTF (stderr,_("\nSUPU %s, %s, %d, test_trail->next_hop =%s"),__FILE__, __func__,__LINE__,GNUNET_i2s(print_peer));
128
129 }
130 }
131 /* SUPU TEST CODE ENDS*/
105 return GNUNET_YES; 132 return GNUNET_YES;
106} 133}
107 134
@@ -191,6 +218,18 @@ GDS_ROUTING_process (enum GNUNET_BLOCK_Type type,
191 return; 218 return;
192} 219}
193 220
221/**
222 * Check if the size of routing table has crossed threshold.
223 * @return
224 */
225int
226GDS_ROUTING_size ()
227{
228 int ret;
229 ret = (GNUNET_CONTAINER_multipeermap_size(routing_table) > ROUTING_TABLE_THRESHOLD) ? 0:1;
230 return ret;
231}
232
194 233
195/** 234/**
196 * Initialize routing subsystem. 235 * Initialize routing subsystem.
diff --git a/src/dht/gnunet-service-xdht_routing.h b/src/dht/gnunet-service-xdht_routing.h
index 92ca5f4f4..147d36480 100644
--- a/src/dht/gnunet-service-xdht_routing.h
+++ b/src/dht/gnunet-service-xdht_routing.h
@@ -37,8 +37,8 @@
37int 37int
38GDS_ROUTING_add (struct GNUNET_PeerIdentity *source, 38GDS_ROUTING_add (struct GNUNET_PeerIdentity *source,
39 struct GNUNET_PeerIdentity *destination_peer, 39 struct GNUNET_PeerIdentity *destination_peer,
40 struct GNUNET_PeerIdentity *next_hop, 40 const struct GNUNET_PeerIdentity *next_hop,
41 const struct GNUNET_PeerIdentity *prev_hop); 41 struct GNUNET_PeerIdentity *prev_hop);
42 42
43 43
44/** 44/**
@@ -77,6 +77,12 @@ GDS_ROUTING_process (enum GNUNET_BLOCK_Type type,
77 const void *data, size_t data_size); 77 const void *data, size_t data_size);
78 78
79/** 79/**
80 * Check if size of routing table is greater than threshold or not.
81 */
82int
83GDS_ROUTING_size (void);
84
85/**
80 * Initialize routing subsystem. 86 * Initialize routing subsystem.
81 */ 87 */
82void 88void