aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorSupriti Singh <supritisingh08@gmail.com>2014-04-07 17:23:33 +0000
committerSupriti Singh <supritisingh08@gmail.com>2014-04-07 17:23:33 +0000
commit395864e0875252a779e783765b955c4193741065 (patch)
tree7c7b2c8a92732c3ce862fb315f886255f18c0b45 /src/dht
parentdaa7b00b515bba437b467e66753a1cda7afa2e3f (diff)
downloadgnunet-395864e0875252a779e783765b955c4193741065.tar.gz
gnunet-395864e0875252a779e783765b955c4193741065.zip
1.Removed GNUNET_CRYPTO_compute_finger_identity
2.Removed myself as the first element of the trail. 3.Multiple entries in the routing table. 4.Put/Get/Monitor from old DHT added back in clients file.
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/gnunet-service-xdht_clients.c1172
-rw-r--r--src/dht/gnunet-service-xdht_clients.h33
-rw-r--r--src/dht/gnunet-service-xdht_datacache.c2
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c984
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.h15
-rw-r--r--src/dht/gnunet-service-xdht_routing.c99
-rw-r--r--src/dht/gnunet-service-xdht_routing.h8
7 files changed, 1716 insertions, 597 deletions
diff --git a/src/dht/gnunet-service-xdht_clients.c b/src/dht/gnunet-service-xdht_clients.c
index 050d8a99e..d3b920551 100644
--- a/src/dht/gnunet-service-xdht_clients.c
+++ b/src/dht/gnunet-service-xdht_clients.c
@@ -21,7 +21,8 @@
21/** 21/**
22 * @file dht/gnunet-service-dht_clients.c 22 * @file dht/gnunet-service-dht_clients.c
23 * @brief GNUnet DHT service's client management code 23 * @brief GNUnet DHT service's client management code
24 * @author Supriti Singh 24 * @author Christian Grothoff
25 * @author Nathan Evans
25 */ 26 */
26 27
27#include "platform.h" 28#include "platform.h"
@@ -34,6 +35,14 @@
34#include "gnunet-service-xdht_neighbours.h" 35#include "gnunet-service-xdht_neighbours.h"
35#include "dht.h" 36#include "dht.h"
36 37
38
39/**
40 * Should routing details be logged to stderr (for debugging)?
41 */
42#define LOG_TRAFFIC(kind,...) GNUNET_log_from (kind, "dht-traffic",__VA_ARGS__)
43
44#define LOG(kind,...) GNUNET_log_from (kind, "dht-clients",__VA_ARGS__)
45
37/** 46/**
38 * Linked list of messages to send to clients. 47 * Linked list of messages to send to clients.
39 */ 48 */
@@ -58,6 +67,7 @@ struct PendingMessage
58 67
59}; 68};
60 69
70
61/** 71/**
62 * Struct containing information about a client, 72 * Struct containing information about a client,
63 * handle to connect to it, and any pending messages 73 * handle to connect to it, and any pending messages
@@ -100,6 +110,129 @@ struct ClientList
100 110
101 111
102/** 112/**
113 * Entry in the local forwarding map for a client's GET request.
114 */
115struct ClientQueryRecord
116{
117
118 /**
119 * The key this request was about
120 */
121 struct GNUNET_HashCode key;
122
123 /**
124 * Client responsible for the request.
125 */
126 struct ClientList *client;
127
128 /**
129 * Extended query (see gnunet_block_lib.h), allocated at the end of this struct.
130 */
131 const void *xquery;
132
133 /**
134 * Replies we have already seen for this request.
135 */
136 struct GNUNET_HashCode *seen_replies;
137
138 /**
139 * Pointer to this nodes heap location in the retry-heap (for fast removal)
140 */
141 struct GNUNET_CONTAINER_HeapNode *hnode;
142
143 /**
144 * What's the delay between re-try operations that we currently use for this
145 * request?
146 */
147 struct GNUNET_TIME_Relative retry_frequency;
148
149 /**
150 * What's the next time we should re-try this request?
151 */
152 struct GNUNET_TIME_Absolute retry_time;
153
154 /**
155 * The unique identifier of this request
156 */
157 uint64_t unique_id;
158
159 /**
160 * Number of bytes in xquery.
161 */
162 size_t xquery_size;
163
164 /**
165 * Number of entries in 'seen_replies'.
166 */
167 unsigned int seen_replies_count;
168
169 /**
170 * Desired replication level
171 */
172 uint32_t replication;
173
174 /**
175 * Any message options for this request
176 */
177 uint32_t msg_options;
178
179 /**
180 * The type for the data for the GET request.
181 */
182 enum GNUNET_BLOCK_Type type;
183
184};
185
186
187/**
188 * Struct containing paremeters of monitoring requests.
189 */
190struct ClientMonitorRecord
191{
192
193 /**
194 * Next element in DLL.
195 */
196 struct ClientMonitorRecord *next;
197
198 /**
199 * Previous element in DLL.
200 */
201 struct ClientMonitorRecord *prev;
202
203 /**
204 * Type of blocks that are of interest
205 */
206 enum GNUNET_BLOCK_Type type;
207
208 /**
209 * Key of data of interest, NULL for all.
210 */
211 struct GNUNET_HashCode *key;
212
213 /**
214 * Flag whether to notify about GET messages.
215 */
216 int16_t get;
217
218 /**
219 * Flag whether to notify about GET_REPONSE messages.
220 */
221 int16_t get_resp;
222
223 /**
224 * Flag whether to notify about PUT messages.
225 */
226 uint16_t put;
227
228 /**
229 * Client to notify of these requests.
230 */
231 struct ClientList *client;
232};
233
234
235/**
103 * List of active clients. 236 * List of active clients.
104 */ 237 */
105static struct ClientList *client_head; 238static struct ClientList *client_head;
@@ -110,11 +243,40 @@ static struct ClientList *client_head;
110static struct ClientList *client_tail; 243static struct ClientList *client_tail;
111 244
112/** 245/**
246 * List of active monitoring requests.
247 */
248static struct ClientMonitorRecord *monitor_head;
249
250/**
251 * List of active monitoring requests.
252 */
253static struct ClientMonitorRecord *monitor_tail;
254
255/**
256 * Hashmap for fast key based lookup, maps keys to `struct ClientQueryRecord` entries.
257 */
258static struct GNUNET_CONTAINER_MultiHashMap *forward_map;
259
260/**
261 * Heap with all of our client's request, sorted by retry time (earliest on top).
262 */
263static struct GNUNET_CONTAINER_Heap *retry_heap;
264
265/**
266 * Task that re-transmits requests (using retry_heap).
267 */
268static GNUNET_SCHEDULER_TaskIdentifier retry_task;
269
270
271/**
113 * Task run to check for messages that need to be sent to a client. 272 * Task run to check for messages that need to be sent to a client.
114 * 273 *
115 * @param client a ClientList, containing the client and any messages to be sent to it 274 * @param client a ClientList, containing the client and any messages to be sent to it
116 */ 275 */
117static void process_pending_messages (struct ClientList *client); 276static void
277process_pending_messages (struct ClientList *client);
278
279
118/** 280/**
119 * Callback called as a result of issuing a GNUNET_SERVER_notify_transmit_ready 281 * Callback called as a result of issuing a GNUNET_SERVER_notify_transmit_ready
120 * request. A ClientList is passed as closure, take the head of the list 282 * request. A ClientList is passed as closure, take the head of the list
@@ -208,6 +370,41 @@ add_pending_message (struct ClientList *client,
208 process_pending_messages (client); 370 process_pending_messages (client);
209} 371}
210 372
373
374/**
375 * Closure for 'forward_reply'
376 */
377struct ForwardReplyContext
378{
379
380 /**
381 * Actual message to send to matching clients.
382 */
383 struct PendingMessage *pm;
384
385 /**
386 * Embedded payload.
387 */
388 const void *data;
389
390 /**
391 * Type of the data.
392 */
393 enum GNUNET_BLOCK_Type type;
394
395 /**
396 * Number of bytes in data.
397 */
398 size_t data_size;
399
400 /**
401 * Do we need to copy 'pm' because it was already used?
402 */
403 int do_copy;
404
405};
406
407
211/** 408/**
212 * Find a client if it exists, add it otherwise. 409 * Find a client if it exists, add it otherwise.
213 * 410 *
@@ -235,118 +432,476 @@ find_active_client (struct GNUNET_SERVER_Client *client)
235 432
236 433
237/** 434/**
238 * SUPU: Call made from dht_api.c 435 * Iterator over hash map entries that frees all entries
239 * Handler for monitor stop messages 436 * associated with the given client.
240 * 437 *
241 * @param cls closure for the service 438 * @param cls client to search for in source routes
242 * @param client the client we received this message from 439 * @param key current key code (ignored)
243 * @param message the actual message received 440 * @param value value in the hash map, a ClientQueryRecord
441 * @return #GNUNET_YES (we should continue to iterate)
442 */
443static int
444remove_client_records (void *cls, const struct GNUNET_HashCode * key, void *value)
445{
446 struct ClientList *client = cls;
447 struct ClientQueryRecord *record = value;
448
449 if (record->client != client)
450 return GNUNET_YES;
451 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
452 "Removing client %p's record for key %s\n", client,
453 GNUNET_h2s (key));
454 GNUNET_assert (GNUNET_YES ==
455 GNUNET_CONTAINER_multihashmap_remove (forward_map, key,
456 record));
457 if (NULL != record->hnode)
458 GNUNET_CONTAINER_heap_remove_node (record->hnode);
459 GNUNET_array_grow (record->seen_replies, record->seen_replies_count, 0);
460 GNUNET_free (record);
461 return GNUNET_YES;
462}
463
464
465/**
466 * Iterator over hash map entries that send a given reply to
467 * each of the matching clients. With some tricky recycling
468 * of the buffer.
244 * 469 *
470 * @param cls the 'struct ForwardReplyContext'
471 * @param key current key
472 * @param value value in the hash map, a ClientQueryRecord
473 * @return GNUNET_YES (we should continue to iterate),
474 * if the result is mal-formed, GNUNET_NO
245 */ 475 */
246static void 476static int
247handle_dht_local_monitor_stop (void *cls, struct GNUNET_SERVER_Client *client, 477forward_reply (void *cls, const struct GNUNET_HashCode * key, void *value)
248 const struct GNUNET_MessageHeader *message)
249{ 478{
250 //const struct GNUNET_DHT_MonitorStartStopMessage *msg; 479 struct ForwardReplyContext *frc = cls;
480 struct ClientQueryRecord *record = value;
481 struct PendingMessage *pm;
482 struct GNUNET_DHT_ClientResultMessage *reply;
483 enum GNUNET_BLOCK_EvaluationResult eval;
484 int do_free;
485 struct GNUNET_HashCode ch;
486 unsigned int i;
487
488 LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG,
489 "R5N CLIENT-RESULT %s\n",
490 GNUNET_h2s_full (key));
491 if ((record->type != GNUNET_BLOCK_TYPE_ANY) && (record->type != frc->type))
492 {
493 LOG (GNUNET_ERROR_TYPE_DEBUG,
494 "Record type missmatch, not passing request for key %s to local client\n",
495 GNUNET_h2s (key));
496 GNUNET_STATISTICS_update (GDS_stats,
497 gettext_noop
498 ("# Key match, type mismatches in REPLY to CLIENT"),
499 1, GNUNET_NO);
500 return GNUNET_YES; /* type mismatch */
501 }
502 GNUNET_CRYPTO_hash (frc->data, frc->data_size, &ch);
503 for (i = 0; i < record->seen_replies_count; i++)
504 if (0 == memcmp (&record->seen_replies[i], &ch, sizeof (struct GNUNET_HashCode)))
505 {
506 LOG (GNUNET_ERROR_TYPE_DEBUG,
507 "Duplicate reply, not passing request for key %s to local client\n",
508 GNUNET_h2s (key));
509 GNUNET_STATISTICS_update (GDS_stats,
510 gettext_noop
511 ("# Duplicate REPLIES to CLIENT request dropped"),
512 1, GNUNET_NO);
513 return GNUNET_YES; /* duplicate */
514 }
515 eval =
516 GNUNET_BLOCK_evaluate (GDS_block_context, record->type, key, NULL, 0,
517 record->xquery, record->xquery_size, frc->data,
518 frc->data_size);
519 LOG (GNUNET_ERROR_TYPE_DEBUG,
520 "Evaluation result is %d for key %s for local client's query\n",
521 (int) eval, GNUNET_h2s (key));
522 switch (eval)
523 {
524 case GNUNET_BLOCK_EVALUATION_OK_LAST:
525 do_free = GNUNET_YES;
526 break;
527 case GNUNET_BLOCK_EVALUATION_OK_MORE:
528 GNUNET_array_append (record->seen_replies, record->seen_replies_count, ch);
529 do_free = GNUNET_NO;
530 break;
531 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
532 /* should be impossible to encounter here */
533 GNUNET_break (0);
534 return GNUNET_YES;
535 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
536 GNUNET_break_op (0);
537 return GNUNET_NO;
538 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
539 GNUNET_break (0);
540 return GNUNET_NO;
541 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
542 GNUNET_break (0);
543 return GNUNET_NO;
544 case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
545 return GNUNET_YES;
546 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
547 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
548 _("Unsupported block type (%u) in request!\n"), record->type);
549 return GNUNET_NO;
550 default:
551 GNUNET_break (0);
552 return GNUNET_NO;
553 }
554 if (GNUNET_NO == frc->do_copy)
555 {
556 /* first time, we can use the original data */
557 pm = frc->pm;
558 frc->do_copy = GNUNET_YES;
559 }
560 else
561 {
562 /* two clients waiting for same reply, must copy for queueing */
563 pm = GNUNET_malloc (sizeof (struct PendingMessage) +
564 ntohs (frc->pm->msg->size));
565 memcpy (pm, frc->pm,
566 sizeof (struct PendingMessage) + ntohs (frc->pm->msg->size));
567 pm->next = pm->prev = NULL;
568 pm->msg = (struct GNUNET_MessageHeader *) &pm[1];
569 }
570 GNUNET_STATISTICS_update (GDS_stats,
571 gettext_noop ("# RESULTS queued for clients"), 1,
572 GNUNET_NO);
573 reply = (struct GNUNET_DHT_ClientResultMessage *) &pm[1];
574 reply->unique_id = record->unique_id;
575 LOG (GNUNET_ERROR_TYPE_DEBUG,
576 "Queueing reply to query %s for client %p\n",
577 GNUNET_h2s (key),
578 record->client->client_handle);
579 add_pending_message (record->client, pm);
580 if (GNUNET_YES == do_free)
581 remove_client_records (record->client, key, record);
582 return GNUNET_YES;
251} 583}
252 584
253 585
254/** 586/**
255 * SUPU: Monitor call made from dht_api.c 587 * Handle a reply we've received from another peer. If the reply
256 * Handler for monitor start messages 588 * matches any of our pending queries, forward it to the respective
589 * client(s).
257 * 590 *
258 * @param cls closure for the service 591 * @param expiration when will the reply expire
259 * @param client the client we received this message from 592 * @param key the query this reply is for
260 * @param message the actual message received 593 * @param get_path_length number of peers in @a get_path
594 * @param get_path path the reply took on get
595 * @param put_path_length number of peers in @a put_path
596 * @param put_path path the reply took on put
597 * @param type type of the reply
598 * @param data_size number of bytes in @a data
599 * @param data application payload data
600 */
601void
602GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration,
603 const struct GNUNET_HashCode *key,
604 unsigned int get_path_length,
605 const struct GNUNET_PeerIdentity *get_path,
606 unsigned int put_path_length,
607 const struct GNUNET_PeerIdentity *put_path,
608 enum GNUNET_BLOCK_Type type, size_t data_size,
609 const void *data)
610{
611 struct ForwardReplyContext frc;
612 struct PendingMessage *pm;
613 struct GNUNET_DHT_ClientResultMessage *reply;
614 struct GNUNET_PeerIdentity *paths;
615 size_t msize;
616
617 LOG (GNUNET_ERROR_TYPE_DEBUG,
618 "reply for key %s\n",
619 GNUNET_h2s (key));
620
621 if (NULL == GNUNET_CONTAINER_multihashmap_get (forward_map, key))
622 {
623 GNUNET_STATISTICS_update (GDS_stats,
624 gettext_noop
625 ("# REPLIES ignored for CLIENTS (no match)"), 1,
626 GNUNET_NO);
627 return; /* no matching request, fast exit! */
628 }
629 msize =
630 sizeof (struct GNUNET_DHT_ClientResultMessage) + data_size +
631 (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity);
632 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
633 {
634 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
635 _("Could not pass reply to client, message too big!\n"));
636 return;
637 }
638 pm = GNUNET_malloc (msize + sizeof (struct PendingMessage));
639 reply = (struct GNUNET_DHT_ClientResultMessage *) &pm[1];
640 pm->msg = &reply->header;
641 reply->header.size = htons ((uint16_t) msize);
642 reply->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT);
643 reply->type = htonl (type);
644 reply->get_path_length = htonl (get_path_length);
645 reply->put_path_length = htonl (put_path_length);
646 reply->unique_id = 0; /* filled in later */
647 reply->expiration = GNUNET_TIME_absolute_hton (expiration);
648 reply->key = *key;
649 paths = (struct GNUNET_PeerIdentity *) &reply[1];
650 memcpy (paths, put_path,
651 sizeof (struct GNUNET_PeerIdentity) * put_path_length);
652 memcpy (&paths[put_path_length], get_path,
653 sizeof (struct GNUNET_PeerIdentity) * get_path_length);
654 memcpy (&paths[get_path_length + put_path_length], data, data_size);
655 frc.do_copy = GNUNET_NO;
656 frc.pm = pm;
657 frc.data = data;
658 frc.data_size = data_size;
659 frc.type = type;
660 GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, key, &forward_reply,
661 &frc);
662
663 if (GNUNET_NO == frc.do_copy)
664 {
665 /* did not match any of the requests, free! */
666 GNUNET_STATISTICS_update (GDS_stats,
667 gettext_noop
668 ("# REPLIES ignored for CLIENTS (no match)"), 1,
669 GNUNET_NO);
670 GNUNET_free (pm);
671 }
672}
673
674/**
675 * Check if some client is monitoring GET messages and notify
676 * them in that case.
261 * 677 *
678 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
679 * @param type The type of data in the request.
680 * @param hop_count Hop count so far.
681 * @param path_length number of entries in path (or 0 if not recorded).
682 * @param path peers on the GET path (or NULL if not recorded).
683 * @param desired_replication_level Desired replication level.
684 * @param key Key of the requested data.
262 */ 685 */
263static void 686void
264handle_dht_local_monitor (void *cls, struct GNUNET_SERVER_Client *client, 687GDS_CLIENTS_process_get (uint32_t options,
265 const struct GNUNET_MessageHeader *message) 688 enum GNUNET_BLOCK_Type type,
689 uint32_t hop_count,
690 uint32_t desired_replication_level,
691 unsigned int path_length,
692 const struct GNUNET_PeerIdentity *path,
693 const struct GNUNET_HashCode * key)
266{ 694{
267 //const struct GNUNET_DHT_MonitorStartStopMessage *msg; 695 struct ClientMonitorRecord *m;
268 /* FIXME: At the moment I don't know exact usage of monitor message. But most 696 struct ClientList **cl;
269 probably it will be just copy and paste from old implementation. */ 697 unsigned int cl_size;
698
699 cl = NULL;
700 cl_size = 0;
701 for (m = monitor_head; NULL != m; m = m->next)
702 {
703 if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) &&
704 (NULL == m->key ||
705 memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0))
706 {
707 struct PendingMessage *pm;
708 struct GNUNET_DHT_MonitorGetMessage *mmsg;
709 struct GNUNET_PeerIdentity *msg_path;
710 size_t msize;
711 unsigned int i;
712
713 /* Don't send duplicates */
714 for (i = 0; i < cl_size; i++)
715 if (cl[i] == m->client)
716 break;
717 if (i < cl_size)
718 continue;
719 GNUNET_array_append (cl, cl_size, m->client);
720
721 msize = path_length * sizeof (struct GNUNET_PeerIdentity);
722 msize += sizeof (struct GNUNET_DHT_MonitorGetMessage);
723 msize += sizeof (struct PendingMessage);
724 pm = GNUNET_malloc (msize);
725 mmsg = (struct GNUNET_DHT_MonitorGetMessage *) &pm[1];
726 pm->msg = &mmsg->header;
727 mmsg->header.size = htons (msize - sizeof (struct PendingMessage));
728 mmsg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET);
729 mmsg->options = htonl(options);
730 mmsg->type = htonl(type);
731 mmsg->hop_count = htonl(hop_count);
732 mmsg->desired_replication_level = htonl(desired_replication_level);
733 mmsg->get_path_length = htonl(path_length);
734 memcpy (&mmsg->key, key, sizeof (struct GNUNET_HashCode));
735 msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
736 if (path_length > 0)
737 memcpy (msg_path, path,
738 path_length * sizeof (struct GNUNET_PeerIdentity));
739 add_pending_message (m->client, pm);
740 }
741 }
742 GNUNET_free_non_null (cl);
270} 743}
271 744
272 745
273/**SUPU: Call to this function is made whenever a client does not want the 746/**
274 * get request any more. There is a function in dht_api.c but I don't know 747 * Check if some client is monitoring PUT messages and notify
275 * yet how the call is made to this function. 748 * them in that case.
276 * Handler for any generic DHT stop messages, calls the appropriate handler
277 * depending on message type (if processed locally)
278 *
279 * @param cls closure for the service
280 * @param client the client we received this message from
281 * @param message the actual message received
282 * 749 *
750 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
751 * @param type The type of data in the request.
752 * @param hop_count Hop count so far.
753 * @param path_length number of entries in path (or 0 if not recorded).
754 * @param path peers on the PUT path (or NULL if not recorded).
755 * @param desired_replication_level Desired replication level.
756 * @param exp Expiration time of the data.
757 * @param key Key under which data is to be stored.
758 * @param data Pointer to the data carried.
759 * @param size Number of bytes in data.
760 */
761void
762GDS_CLIENTS_process_put (uint32_t options,
763 enum GNUNET_BLOCK_Type type,
764 uint32_t hop_count,
765 uint32_t desired_replication_level,
766 unsigned int path_length,
767 const struct GNUNET_PeerIdentity *path,
768 struct GNUNET_TIME_Absolute exp,
769 const struct GNUNET_HashCode * key,
770 const void *data,
771 size_t size)
772{
773 struct ClientMonitorRecord *m;
774 struct ClientList **cl;
775 unsigned int cl_size;
776
777 cl = NULL;
778 cl_size = 0;
779 for (m = monitor_head; NULL != m; m = m->next)
780 {
781 if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) &&
782 (NULL == m->key ||
783 memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0))
784 {
785 struct PendingMessage *pm;
786 struct GNUNET_DHT_MonitorPutMessage *mmsg;
787 struct GNUNET_PeerIdentity *msg_path;
788 size_t msize;
789 unsigned int i;
790
791 /* Don't send duplicates */
792 for (i = 0; i < cl_size; i++)
793 if (cl[i] == m->client)
794 break;
795 if (i < cl_size)
796 continue;
797 GNUNET_array_append (cl, cl_size, m->client);
798
799 msize = size;
800 msize += path_length * sizeof (struct GNUNET_PeerIdentity);
801 msize += sizeof (struct GNUNET_DHT_MonitorPutMessage);
802 msize += sizeof (struct PendingMessage);
803 pm = GNUNET_malloc (msize);
804 mmsg = (struct GNUNET_DHT_MonitorPutMessage *) &pm[1];
805 pm->msg = (struct GNUNET_MessageHeader *) mmsg;
806 mmsg->header.size = htons (msize - sizeof (struct PendingMessage));
807 mmsg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT);
808 mmsg->options = htonl(options);
809 mmsg->type = htonl(type);
810 mmsg->hop_count = htonl(hop_count);
811 mmsg->desired_replication_level = htonl(desired_replication_level);
812 mmsg->put_path_length = htonl(path_length);
813 msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
814 if (path_length > 0)
815 {
816 memcpy (msg_path, path,
817 path_length * sizeof (struct GNUNET_PeerIdentity));
818 }
819 mmsg->expiration_time = GNUNET_TIME_absolute_hton(exp);
820 memcpy (&mmsg->key, key, sizeof (struct GNUNET_HashCode));
821 if (size > 0)
822 memcpy (&msg_path[path_length], data, size);
823 add_pending_message (m->client, pm);
824 }
825 }
826 GNUNET_free_non_null (cl);
827}
828
829
830/**
831 * Route the given request via the DHT.
283 */ 832 */
284static void 833static void
285handle_dht_local_get_stop (void *cls, struct GNUNET_SERVER_Client *client, 834transmit_request (struct ClientQueryRecord *cqr)
286 const struct GNUNET_MessageHeader *message)
287{ 835{
288 //const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg; 836 GNUNET_STATISTICS_update (GDS_stats,
289 /* FIXME: Whats the use of get_stop. A client notifies the server to stop asking 837 gettext_noop
290 for the get message. But in case of x-vine, it asks for get only once. So, 838 ("# GET requests from clients injected"), 1,
291 when it has already send the get message, after that if client asks it to 839 GNUNET_NO);
292 stop, it really can't do anything. Its better to wait for the result, discard 840
293 it and don't communicate with client about the result instead of generating 841 LOG (GNUNET_ERROR_TYPE_DEBUG,
294 more traffic.*/ 842 "Initiating GET for %s, replication %u, already have %u replies\n",
843 GNUNET_h2s (&cqr->key),
844 cqr->replication,
845 cqr->seen_replies_count);
846#if 0
847 /* FIXME: Change it to your own handle_get. */
848 GDS_NEIGHBOURS_handle_get (cqr->type, cqr->msg_options, cqr->replication,
849 0 /* hop count */ ,
850 &cqr->key, cqr->xquery, cqr->xquery_size, reply_bf,
851 reply_bf_mutator, peer_bf);
852#endif
853
854
855 /* exponential back-off for retries.
856 * max GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */
857 cqr->retry_frequency = GNUNET_TIME_STD_BACKOFF (cqr->retry_frequency);
858 cqr->retry_time = GNUNET_TIME_relative_to_absolute (cqr->retry_frequency);
295} 859}
296 860
861
297/** 862/**
298 * FIXME: Call to this function is made whenever we have a get request. 863 * Task that looks at the 'retry_heap' and transmits all of the requests
299 * Handler for DHT GET messages from the client. 864 * on the heap that are ready for transmission. Then re-schedules
865 * itself (unless the heap is empty).
300 * 866 *
301 * @param cls closure for the service 867 * @param cls unused
302 * @param client the client we received this message from 868 * @param tc scheduler context
303 * @param message the actual message received
304 */ 869 */
305static void 870static void
306handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client, 871transmit_next_request_task (void *cls,
307 const struct GNUNET_MessageHeader *message) 872 const struct GNUNET_SCHEDULER_TaskContext *tc)
308{ 873{
309 struct GNUNET_DHT_ClientGetMessage *get_msg; 874 struct ClientQueryRecord *cqr;
310 struct GNUNET_PeerIdentity *get_path; 875 struct GNUNET_TIME_Relative delay;
311 struct GNUNET_PeerIdentity *my_identity; 876
312 unsigned int get_path_length; 877 retry_task = GNUNET_SCHEDULER_NO_TASK;
313 uint16_t size; 878 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
314
315 size = ntohs (message->size);
316 if (size < sizeof (struct GNUNET_DHT_ClientGetMessage))
317 {
318 GNUNET_break (0);
319 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
320 return; 879 return;
880 while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap)))
881 {
882 cqr->hnode = NULL;
883 delay = GNUNET_TIME_absolute_get_remaining (cqr->retry_time);
884 if (delay.rel_value_us > 0)
885 {
886 cqr->hnode =
887 GNUNET_CONTAINER_heap_insert (retry_heap, cqr,
888 cqr->retry_time.abs_value_us);
889 retry_task =
890 GNUNET_SCHEDULER_add_delayed (delay, &transmit_next_request_task,
891 NULL);
892 return;
893 }
894 transmit_request (cqr);
895 cqr->hnode =
896 GNUNET_CONTAINER_heap_insert (retry_heap, cqr,
897 cqr->retry_time.abs_value_us);
321 } 898 }
322
323 get_msg = (struct GNUNET_DHT_ClientGetMessage *) message;
324
325 /* FIXME: Search locally? Why should we always search locally?
326 Current implementation of datacache needs to be modified. If found here, then
327 notify the requesting client. */
328
329 /* FIXME: Call GDS_NEIGHBOURS_handle_get
330 Here you need to remember the whole path because you need to travel that path
331 and reach back here with the result. So, you should send your own id, client
332 id, get path, get path length. You also need to add yourself to the get path. */
333 my_identity = GDS_NEIGHBOURS_get_id();
334 get_path = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
335 memcpy (get_path, &my_identity, sizeof (struct GNUNET_PeerIdentity));
336 get_path_length = 1;
337
338 /* FIXME:
339 * 1. Find some unique identifier for the client.
340 * 2. Also, I don't know the usage of block, replication and type. So, I
341 * am not sending the parameters now. */
342 GDS_NEIGHBOURS_handle_get (my_identity, get_path, get_path_length,
343 &(get_msg->key), NULL, NULL, NULL);
344
345} 899}
346 900
347 901
348/** 902/**
349 * Handler for PUT messages. 903 * Handler for PUT messages.
904 *
350 * @param cls closure for the service 905 * @param cls closure for the service
351 * @param client the client we received this message from 906 * @param client the client we received this message from
352 * @param message the actual message received 907 * @param message the actual message received
@@ -355,10 +910,10 @@ static void
355handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client, 910handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client,
356 const struct GNUNET_MessageHeader *message) 911 const struct GNUNET_MessageHeader *message)
357{ 912{
358 struct GNUNET_DHT_ClientPutMessage *put_msg; 913 const struct GNUNET_DHT_ClientPutMessage *put_msg;
359 struct GNUNET_DHT_ClientPutConfirmationMessage *conf;
360 struct PendingMessage *pm; 914 struct PendingMessage *pm;
361 uint16_t size; /* FIXME: When to use size_t and when uint16_t */ 915 struct GNUNET_DHT_ClientPutConfirmationMessage *conf;
916 uint16_t size;
362 917
363 size = ntohs (message->size); 918 size = ntohs (message->size);
364 if (size < sizeof (struct GNUNET_DHT_ClientPutMessage)) 919 if (size < sizeof (struct GNUNET_DHT_ClientPutMessage))
@@ -367,19 +922,32 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client,
367 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 922 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
368 return; 923 return;
369 } 924 }
925 GNUNET_STATISTICS_update (GDS_stats,
926 gettext_noop
927 ("# PUT requests received from clients"), 1,
928 GNUNET_NO);
929 put_msg = (const struct GNUNET_DHT_ClientPutMessage *) message;
930 LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "R5N CLIENT-PUT %s\n",
931 GNUNET_h2s_full (&put_msg->key));
932 /* give to local clients */
933 LOG (GNUNET_ERROR_TYPE_DEBUG,
934 "Handling local PUT of %u-bytes for query %s\n",
935 size - sizeof (struct GNUNET_DHT_ClientPutMessage),
936 GNUNET_h2s (&put_msg->key));
370 937
371 /* FIXME:Should we define put_msg as const? */ 938 GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (put_msg->expiration),
372 put_msg = (struct GNUNET_DHT_ClientPutMessage *) message; 939 &put_msg->key, 0, NULL, 0, NULL,
373 940 ntohl (put_msg->type),
374 /* store locally. FIXME: Is it secure to allow each peer to store the data? */ 941 size - sizeof (struct GNUNET_DHT_ClientPutMessage),
942 &put_msg[1]);
943 /* store locally */
375 GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put_msg->expiration), 944 GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put_msg->expiration),
376 &put_msg->key, 0, NULL, ntohl (put_msg->type), 945 &put_msg->key, 0, NULL, ntohl (put_msg->type),
377 size - sizeof (struct GNUNET_DHT_ClientPutMessage), 946 size - sizeof (struct GNUNET_DHT_ClientPutMessage),
378 &put_msg[1]); 947 &put_msg[1]);
379 948
380 /* FIXME: Right now I have just kept all the fields from the old function. 949 /* FIXME: At the moment we don't use replication in x-vine. But keep it for
381 It may be possible that most of them are not needed. Check and remove if 950 time being. Check all the fields again. */
382 not needed. Usage of replication, options and type is still not clear. */
383 GDS_NEIGHBOURS_handle_put (ntohl (put_msg->type), ntohl (put_msg->options), 951 GDS_NEIGHBOURS_handle_put (ntohl (put_msg->type), ntohl (put_msg->options),
384 ntohl (put_msg->desired_replication_level), 952 ntohl (put_msg->desired_replication_level),
385 GNUNET_TIME_absolute_ntoh (put_msg->expiration), 953 GNUNET_TIME_absolute_ntoh (put_msg->expiration),
@@ -387,10 +955,19 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client,
387 &put_msg->key, 0, NULL, &put_msg[1], 955 &put_msg->key, 0, NULL, &put_msg[1],
388 size - 956 size -
389 sizeof (struct GNUNET_DHT_ClientPutMessage), 957 sizeof (struct GNUNET_DHT_ClientPutMessage),
390 NULL, NULL, NULL); 958 NULL, 0, NULL);
959
960 GDS_CLIENTS_process_put (ntohl (put_msg->options),
961 ntohl (put_msg->type),
962 0,
963 ntohl (put_msg->desired_replication_level),
964 1,
965 GDS_NEIGHBOURS_get_id(),
966 GNUNET_TIME_absolute_ntoh (put_msg->expiration),
967 &put_msg->key,
968 &put_msg[1],
969 size - sizeof (struct GNUNET_DHT_ClientPutMessage));
391 970
392 /* FIXME: Here we send back the confirmation before verifying if put was successful
393 or not. */
394 pm = GNUNET_malloc (sizeof (struct PendingMessage) + 971 pm = GNUNET_malloc (sizeof (struct PendingMessage) +
395 sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage)); 972 sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage));
396 conf = (struct GNUNET_DHT_ClientPutConfirmationMessage *) &pm[1]; 973 conf = (struct GNUNET_DHT_ClientPutConfirmationMessage *) &pm[1];
@@ -403,6 +980,334 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client,
403 GNUNET_SERVER_receive_done (client, GNUNET_OK); 980 GNUNET_SERVER_receive_done (client, GNUNET_OK);
404} 981}
405 982
983
984/**
985 * Handler for DHT GET messages from the client.
986 *
987 * @param cls closure for the service
988 * @param client the client we received this message from
989 * @param message the actual message received
990 */
991static void
992handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client,
993 const struct GNUNET_MessageHeader *message)
994{
995 const struct GNUNET_DHT_ClientGetMessage *get;
996 struct ClientQueryRecord *cqr;
997 size_t xquery_size;
998 const char *xquery;
999 uint16_t size;
1000
1001 size = ntohs (message->size);
1002 if (size < sizeof (struct GNUNET_DHT_ClientGetMessage))
1003 {
1004 GNUNET_break (0);
1005 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1006 return;
1007 }
1008 xquery_size = size - sizeof (struct GNUNET_DHT_ClientGetMessage);
1009 get = (const struct GNUNET_DHT_ClientGetMessage *) message;
1010 xquery = (const char *) &get[1];
1011 GNUNET_STATISTICS_update (GDS_stats,
1012 gettext_noop
1013 ("# GET requests received from clients"), 1,
1014 GNUNET_NO);
1015 LOG (GNUNET_ERROR_TYPE_DEBUG,
1016 "Received GET request for %s from local client %p, xq: %.*s\n",
1017 GNUNET_h2s (&get->key), client, xquery_size, xquery);
1018
1019 LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "R5N CLIENT-GET %s\n",
1020 GNUNET_h2s_full (&get->key));
1021
1022
1023 cqr = GNUNET_malloc (sizeof (struct ClientQueryRecord) + xquery_size);
1024 cqr->key = get->key;
1025 cqr->client = find_active_client (client);
1026 cqr->xquery = (void *) &cqr[1];
1027 memcpy (&cqr[1], xquery, xquery_size);
1028 cqr->hnode = GNUNET_CONTAINER_heap_insert (retry_heap, cqr, 0);
1029 cqr->retry_frequency = GNUNET_TIME_UNIT_SECONDS;
1030 cqr->retry_time = GNUNET_TIME_absolute_get ();
1031 cqr->unique_id = get->unique_id;
1032 cqr->xquery_size = xquery_size;
1033 cqr->replication = ntohl (get->desired_replication_level);
1034 cqr->msg_options = ntohl (get->options);
1035 cqr->type = ntohl (get->type);
1036 // FIXME use cqr->key, set multihashmap create to GNUNET_YES
1037 GNUNET_CONTAINER_multihashmap_put (forward_map, &get->key, cqr,
1038 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1039 GDS_CLIENTS_process_get (ntohl (get->options),
1040 ntohl (get->type),
1041 0,
1042 ntohl (get->desired_replication_level),
1043 1,
1044 GDS_NEIGHBOURS_get_id(),
1045 &get->key);
1046 /* start remote requests */
1047 if (GNUNET_SCHEDULER_NO_TASK != retry_task)
1048 GNUNET_SCHEDULER_cancel (retry_task);
1049 retry_task = GNUNET_SCHEDULER_add_now (&transmit_next_request_task, NULL);
1050 /* perform local lookup */
1051 GDS_DATACACHE_handle_get (&get->key, cqr->type, cqr->xquery, xquery_size,
1052 NULL, 0);
1053 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1054}
1055
1056
1057/**
1058 * Closure for 'find_by_unique_id'.
1059 */
1060struct FindByUniqueIdContext
1061{
1062 /**
1063 * Where to store the result, if found.
1064 */
1065 struct ClientQueryRecord *cqr;
1066
1067 uint64_t unique_id;
1068};
1069
1070
1071/**
1072 * Function called for each existing DHT record for the given
1073 * query. Checks if it matches the UID given in the closure
1074 * and if so returns the entry as a result.
1075 *
1076 * @param cls the search context
1077 * @param key query for the lookup (not used)
1078 * @param value the 'struct ClientQueryRecord'
1079 * @return GNUNET_YES to continue iteration (result not yet found)
1080 */
1081static int
1082find_by_unique_id (void *cls,
1083 const struct GNUNET_HashCode *key,
1084 void *value)
1085{
1086 struct FindByUniqueIdContext *fui_ctx = cls;
1087 struct ClientQueryRecord *cqr = value;
1088
1089 if (cqr->unique_id != fui_ctx->unique_id)
1090 return GNUNET_YES;
1091 fui_ctx->cqr = cqr;
1092 return GNUNET_NO;
1093}
1094
1095
1096/**
1097 * Handler for "GET result seen" messages from the client.
1098 *
1099 * @param cls closure for the service
1100 * @param client the client we received this message from
1101 * @param message the actual message received
1102 */
1103static void
1104handle_dht_local_get_result_seen (void *cls, struct GNUNET_SERVER_Client *client,
1105 const struct GNUNET_MessageHeader *message)
1106{
1107 const struct GNUNET_DHT_ClientGetResultSeenMessage *seen;
1108 uint16_t size;
1109 unsigned int hash_count;
1110 unsigned int old_count;
1111 const struct GNUNET_HashCode *hc;
1112 struct FindByUniqueIdContext fui_ctx;
1113 struct ClientQueryRecord *cqr;
1114
1115 size = ntohs (message->size);
1116 if (size < sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage))
1117 {
1118 GNUNET_break (0);
1119 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1120 return;
1121 }
1122 seen = (const struct GNUNET_DHT_ClientGetResultSeenMessage *) message;
1123 hash_count = (size - sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) / sizeof (struct GNUNET_HashCode);
1124 if (size != sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage) + hash_count * sizeof (struct GNUNET_HashCode))
1125 {
1126 GNUNET_break (0);
1127 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1128 return;
1129 }
1130 hc = (const struct GNUNET_HashCode*) &seen[1];
1131 fui_ctx.unique_id = seen->unique_id;
1132 fui_ctx.cqr = NULL;
1133 GNUNET_CONTAINER_multihashmap_get_multiple (forward_map,
1134 &seen->key,
1135 &find_by_unique_id,
1136 &fui_ctx);
1137 if (NULL == (cqr = fui_ctx.cqr))
1138 {
1139 GNUNET_break (0);
1140 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1141 return;
1142 }
1143 /* finally, update 'seen' list */
1144 old_count = cqr->seen_replies_count;
1145 GNUNET_array_grow (cqr->seen_replies,
1146 cqr->seen_replies_count,
1147 cqr->seen_replies_count + hash_count);
1148 memcpy (&cqr->seen_replies[old_count],
1149 hc,
1150 sizeof (struct GNUNET_HashCode) * hash_count);
1151}
1152
1153
1154/**
1155 * Closure for 'remove_by_unique_id'.
1156 */
1157struct RemoveByUniqueIdContext
1158{
1159 /**
1160 * Client that issued the removal request.
1161 */
1162 struct ClientList *client;
1163
1164 /**
1165 * Unique ID of the request.
1166 */
1167 uint64_t unique_id;
1168};
1169
1170
1171/**
1172 * Iterator over hash map entries that frees all entries
1173 * that match the given client and unique ID.
1174 *
1175 * @param cls unique ID and client to search for in source routes
1176 * @param key current key code
1177 * @param value value in the hash map, a ClientQueryRecord
1178 * @return GNUNET_YES (we should continue to iterate)
1179 */
1180static int
1181remove_by_unique_id (void *cls, const struct GNUNET_HashCode * key, void *value)
1182{
1183 const struct RemoveByUniqueIdContext *ctx = cls;
1184 struct ClientQueryRecord *record = value;
1185
1186 if (record->unique_id != ctx->unique_id)
1187 return GNUNET_YES;
1188 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1189 "Removing client %p's record for key %s (by unique id)\n",
1190 ctx->client->client_handle, GNUNET_h2s (key));
1191 return remove_client_records (ctx->client, key, record);
1192}
1193
1194
1195/**
1196 * Handler for any generic DHT stop messages, calls the appropriate handler
1197 * depending on message type (if processed locally)
1198 *
1199 * @param cls closure for the service
1200 * @param client the client we received this message from
1201 * @param message the actual message received
1202 *
1203 */
1204static void
1205handle_dht_local_get_stop (void *cls, struct GNUNET_SERVER_Client *client,
1206 const struct GNUNET_MessageHeader *message)
1207{
1208 const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg =
1209 (const struct GNUNET_DHT_ClientGetStopMessage *) message;
1210 struct RemoveByUniqueIdContext ctx;
1211
1212 GNUNET_STATISTICS_update (GDS_stats,
1213 gettext_noop
1214 ("# GET STOP requests received from clients"), 1,
1215 GNUNET_NO);
1216 LOG (GNUNET_ERROR_TYPE_DEBUG,
1217 "Received GET STOP request for %s from local client %p\n",
1218 client, GNUNET_h2s (&dht_stop_msg->key));
1219 ctx.client = find_active_client (client);
1220 ctx.unique_id = dht_stop_msg->unique_id;
1221 GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, &dht_stop_msg->key,
1222 &remove_by_unique_id, &ctx);
1223 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1224}
1225
1226
1227/**
1228 * Handler for monitor start messages
1229 *
1230 * @param cls closure for the service
1231 * @param client the client we received this message from
1232 * @param message the actual message received
1233 *
1234 */
1235static void
1236handle_dht_local_monitor (void *cls, struct GNUNET_SERVER_Client *client,
1237 const struct GNUNET_MessageHeader *message)
1238{
1239 struct ClientMonitorRecord *r;
1240 const struct GNUNET_DHT_MonitorStartStopMessage *msg;
1241
1242 msg = (struct GNUNET_DHT_MonitorStartStopMessage *) message;
1243 r = GNUNET_new (struct ClientMonitorRecord);
1244
1245 r->client = find_active_client(client);
1246 r->type = ntohl(msg->type);
1247 r->get = ntohs(msg->get);
1248 r->get_resp = ntohs(msg->get_resp);
1249 r->put = ntohs(msg->put);
1250 if (0 == ntohs(msg->filter_key))
1251 r->key = NULL;
1252 else
1253 {
1254 r->key = GNUNET_new (struct GNUNET_HashCode);
1255 memcpy (r->key, &msg->key, sizeof (struct GNUNET_HashCode));
1256 }
1257 GNUNET_CONTAINER_DLL_insert (monitor_head, monitor_tail, r);
1258 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1259}
1260
1261
1262/**
1263 * Handler for monitor stop messages
1264 *
1265 * @param cls closure for the service
1266 * @param client the client we received this message from
1267 * @param message the actual message received
1268 *
1269 */
1270static void
1271handle_dht_local_monitor_stop (void *cls, struct GNUNET_SERVER_Client *client,
1272 const struct GNUNET_MessageHeader *message)
1273{
1274 struct ClientMonitorRecord *r;
1275 const struct GNUNET_DHT_MonitorStartStopMessage *msg;
1276 int keys_match;
1277
1278 msg = (struct GNUNET_DHT_MonitorStartStopMessage *) message;
1279 r = monitor_head;
1280
1281 while (NULL != r)
1282 {
1283 if (NULL == r->key)
1284 keys_match = (0 == ntohs(msg->filter_key));
1285 else
1286 {
1287 keys_match = (0 != ntohs(msg->filter_key)
1288 && !memcmp(r->key, &msg->key, sizeof(struct GNUNET_HashCode)));
1289 }
1290 if (find_active_client(client) == r->client
1291 && ntohl(msg->type) == r->type
1292 && r->get == msg->get
1293 && r->get_resp == msg->get_resp
1294 && r->put == msg->put
1295 && keys_match
1296 )
1297 {
1298 GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, r);
1299 GNUNET_free_non_null (r->key);
1300 GNUNET_free (r);
1301 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1302 return; /* Delete only ONE entry */
1303 }
1304 r = r->next;
1305 }
1306
1307 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1308}
1309
1310
406/** 1311/**
407 * Functions with this signature are called whenever a client 1312 * Functions with this signature are called whenever a client
408 * is disconnected on the network level. 1313 * is disconnected on the network level.
@@ -415,26 +1320,46 @@ static void
415handle_client_disconnect (void *cls, 1320handle_client_disconnect (void *cls,
416 struct GNUNET_SERVER_Client *client) 1321 struct GNUNET_SERVER_Client *client)
417{ 1322{
418 /* You should maintain a list of client attached to this service. Then 1323 struct ClientList *pos;
419 search for the correct client and stop all its ongoing activites and 1324 struct PendingMessage *reply;
420 delete it from the list. */ 1325 struct ClientMonitorRecord *monitor;
421}
422 1326
1327 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1328 "Local client %p disconnects\n",
1329 client);
1330 pos = find_active_client (client);
1331 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, pos);
1332 if (pos->transmit_handle != NULL)
1333 GNUNET_SERVER_notify_transmit_ready_cancel (pos->transmit_handle);
1334 while (NULL != (reply = pos->pending_head))
1335 {
1336 GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail, reply);
1337 GNUNET_free (reply);
1338 }
1339 monitor = monitor_head;
1340 while (NULL != monitor)
1341 {
1342 if (monitor->client == pos)
1343 {
1344 struct ClientMonitorRecord *next;
423 1345
424/** 1346 GNUNET_free_non_null (monitor->key);
425 * Get result from neighbours file. 1347 next = monitor->next;
426 */ 1348 GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, monitor);
427void 1349 GNUNET_free (monitor);
428GDS_CLIENTS_process_get_result() 1350 monitor = next;
429{ 1351 }
430 1352 else
1353 monitor = monitor->next;
1354 }
1355 GNUNET_CONTAINER_multihashmap_iterate (forward_map, &remove_client_records,
1356 pos);
1357 GNUNET_free (pos);
431} 1358}
432 1359
433 1360
1361
434/** 1362/**
435 * SUPU: Call to this function is made from gnunet-service-xdht.c
436 * Here we register handlers for each possible kind of message the service
437 * receives from the clients.
438 * Initialize client subsystem. 1363 * Initialize client subsystem.
439 * 1364 *
440 * @param server the initialized server 1365 * @param server the initialized server
@@ -456,19 +1381,42 @@ GDS_CLIENTS_init (struct GNUNET_SERVER_Handle *server)
456 {&handle_dht_local_monitor_stop, NULL, 1381 {&handle_dht_local_monitor_stop, NULL,
457 GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP, 1382 GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP,
458 sizeof (struct GNUNET_DHT_MonitorStartStopMessage)}, 1383 sizeof (struct GNUNET_DHT_MonitorStartStopMessage)},
1384 {&handle_dht_local_get_result_seen, NULL,
1385 GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN, 0},
459 {NULL, NULL, 0, 0} 1386 {NULL, NULL, 0, 0}
460 }; 1387 };
461 1388 forward_map = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_NO);
1389 retry_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
462 GNUNET_SERVER_add_handlers (server, plugin_handlers); 1390 GNUNET_SERVER_add_handlers (server, plugin_handlers);
463 GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); 1391 GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
464} 1392}
465 1393
1394
466/** 1395/**
467 * SUPU: Call made from gnunet-service-dht.c
468 * Shutdown client subsystem. 1396 * Shutdown client subsystem.
469 */ 1397 */
470void 1398void
471GDS_CLIENTS_done () 1399GDS_CLIENTS_done ()
472{ 1400{
473 1401 GNUNET_assert (client_head == NULL);
474} \ No newline at end of file 1402 GNUNET_assert (client_tail == NULL);
1403 if (GNUNET_SCHEDULER_NO_TASK != retry_task)
1404 {
1405 GNUNET_SCHEDULER_cancel (retry_task);
1406 retry_task = GNUNET_SCHEDULER_NO_TASK;
1407 }
1408 if (NULL != retry_heap)
1409 {
1410 GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (retry_heap));
1411 GNUNET_CONTAINER_heap_destroy (retry_heap);
1412 retry_heap = NULL;
1413 }
1414 if (NULL != forward_map)
1415 {
1416 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (forward_map));
1417 GNUNET_CONTAINER_multihashmap_destroy (forward_map);
1418 forward_map = NULL;
1419 }
1420}
1421
1422/* end of gnunet-service-dht_clients.c */
diff --git a/src/dht/gnunet-service-xdht_clients.h b/src/dht/gnunet-service-xdht_clients.h
index 828d2c08a..2aac7f2b0 100644
--- a/src/dht/gnunet-service-xdht_clients.h
+++ b/src/dht/gnunet-service-xdht_clients.h
@@ -21,10 +21,11 @@
21/** 21/**
22 * @file dht/gnunet-service-xdht_clients.h 22 * @file dht/gnunet-service-xdht_clients.h
23 * @brief GNUnet DHT service's client management code 23 * @brief GNUnet DHT service's client management code
24 * @author Supriti Singh 24 * @author Christian Grothoff
25 * @author Nathan Evans
25 */ 26 */
26#ifndef GNUNET_SERVICE_XDHT_CLIENT_H 27#ifndef GNUNET_SERVICE_DHT_CLIENT_H
27#define GNUNET_SERVICE_XDHT_CLIENT_H 28#define GNUNET_SERVICE_DHT_CLIENT_H
28 29
29#include "gnunet_util_lib.h" 30#include "gnunet_util_lib.h"
30#include "gnunet_block_lib.h" 31#include "gnunet_block_lib.h"
@@ -36,17 +37,17 @@
36 * 37 *
37 * @param expiration when will the reply expire 38 * @param expiration when will the reply expire
38 * @param key the query this reply is for 39 * @param key the query this reply is for
39 * @param get_path_length number of peers in 'get_path' 40 * @param get_path_length number of peers in @a get_path
40 * @param get_path path the reply took on get 41 * @param get_path path the reply took on get
41 * @param put_path_length number of peers in 'put_path' 42 * @param put_path_length number of peers in @a put_path
42 * @param put_path path the reply took on put 43 * @param put_path path the reply took on put
43 * @param type type of the reply 44 * @param type type of the reply
44 * @param data_size number of bytes in 'data' 45 * @param data_size number of bytes in @a data
45 * @param data application payload data 46 * @param data application payload data
46 */ 47 */
47void 48void
48GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, 49GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration,
49 const struct GNUNET_HashCode * key, 50 const struct GNUNET_HashCode *key,
50 unsigned int get_path_length, 51 unsigned int get_path_length,
51 const struct GNUNET_PeerIdentity *get_path, 52 const struct GNUNET_PeerIdentity *get_path,
52 unsigned int put_path_length, 53 unsigned int put_path_length,
@@ -74,7 +75,8 @@ GDS_CLIENTS_process_get (uint32_t options,
74 uint32_t desired_replication_level, 75 uint32_t desired_replication_level,
75 unsigned int path_length, 76 unsigned int path_length,
76 const struct GNUNET_PeerIdentity *path, 77 const struct GNUNET_PeerIdentity *path,
77 const struct GNUNET_HashCode * key); 78 const struct GNUNET_HashCode *key);
79
78 80
79/** 81/**
80 * Check if some client is monitoring GET RESP messages and notify 82 * Check if some client is monitoring GET RESP messages and notify
@@ -82,13 +84,13 @@ GDS_CLIENTS_process_get (uint32_t options,
82 * 84 *
83 * @param type The type of data in the result. 85 * @param type The type of data in the result.
84 * @param get_path Peers on GET path (or NULL if not recorded). 86 * @param get_path Peers on GET path (or NULL if not recorded).
85 * @param get_path_length number of entries in get_path. 87 * @param get_path_length number of entries in @a get_path.
86 * @param put_path peers on the PUT path (or NULL if not recorded). 88 * @param put_path peers on the PUT path (or NULL if not recorded).
87 * @param put_path_length number of entries in get_path. 89 * @param put_path_length number of entries in @a get_path.
88 * @param exp Expiration time of the data. 90 * @param exp Expiration time of the data.
89 * @param key Key of the data. 91 * @param key Key of the @a data.
90 * @param data Pointer to the result data. 92 * @param data Pointer to the result data.
91 * @param size Number of bytes in data. 93 * @param size Number of bytes in @a data.
92 */ 94 */
93void 95void
94GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, 96GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type,
@@ -101,6 +103,7 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type,
101 const void *data, 103 const void *data,
102 size_t size); 104 size_t size);
103 105
106
104/** 107/**
105 * Check if some client is monitoring PUT messages and notify 108 * Check if some client is monitoring PUT messages and notify
106 * them in that case. 109 * them in that case.
@@ -129,12 +132,6 @@ GDS_CLIENTS_process_put (uint32_t options,
129 size_t size); 132 size_t size);
130 133
131/** 134/**
132 *
133 */
134void
135GDS_CLIENTS_process_get_result();
136
137/**
138 * Initialize client subsystem. 135 * Initialize client subsystem.
139 * 136 *
140 * @param server the initialized server 137 * @param server the initialized server
diff --git a/src/dht/gnunet-service-xdht_datacache.c b/src/dht/gnunet-service-xdht_datacache.c
index bdc247690..77673cf66 100644
--- a/src/dht/gnunet-service-xdht_datacache.c
+++ b/src/dht/gnunet-service-xdht_datacache.c
@@ -61,7 +61,7 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
61 const void *data) 61 const void *data)
62{ 62{
63 int r; 63 int r;
64 64
65 if (NULL == datacache) 65 if (NULL == datacache)
66 { 66 {
67 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 67 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c
index 4c290895b..aa8f70d12 100644
--- a/src/dht/gnunet-service-xdht_neighbours.c
+++ b/src/dht/gnunet-service-xdht_neighbours.c
@@ -57,7 +57,15 @@
57 * them as they come. 57 * them as they come.
58 * 3. Everywhere you are storing yourself as the first element in the trail. 58 * 3. Everywhere you are storing yourself as the first element in the trail.
59 * It is obviously taking too much space. Try to remove it and think of something 59 * It is obviously taking too much space. Try to remove it and think of something
60 * better. */ 60 * better.
61 4. Choose the correct interval to send finger and verify message.
62 5. Do we need expiration time for trail setup and all other messages? TTL
63 6. In case of trail setup after TTL, we should again send the request but
64 * through a different route. How do we remeber each time which friend we
65 * chose last time for the trail setup. We will need a data structure where we
66 * add entry in finger table add and when setup is done remove it.
67 * 7. I have not added any authentication on messages exachanged between peers.
68 * Only when basic put/get is correct I will add it. */
61 69
62/** 70/**
63 * Maximum possible fingers of a peer. 71 * Maximum possible fingers of a peer.
@@ -85,18 +93,9 @@
85#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2) 93#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
86 94
87/** 95/**
88 * FIXME: Use this variable. Should it be moved to routing.c 96 * Maximum number of trails allowed to go through a friend.
89 * Threshold on routing table entries for a peer.
90 */ 97 */
91#define ROUTING_TABLE_THRESHOLD 64 98#define LINK_THRESHOLD 64
92
93/**
94 * FIXME: Use this variable. When adding an entry in finger table, check
95 * this threshold value. At the moment, its just a random value. Also,
96 * implement teardown feature from the paper.
97 * Threshold on number of peers in a trail length
98 */
99#define TRAIL_LENGTH_THRESHOLD 64
100 99
101 100
102GNUNET_NETWORK_STRUCT_BEGIN 101GNUNET_NETWORK_STRUCT_BEGIN
@@ -208,7 +207,7 @@ struct PeerGetResultMessage
208 * The key of the corresponding GET request. 207 * The key of the corresponding GET request.
209 */ 208 */
210 struct GNUNET_HashCode key; 209 struct GNUNET_HashCode key;
211 210
212 /* put path (if tracked) */ 211 /* put path (if tracked) */
213 212
214 /* get path (if tracked) */ 213 /* get path (if tracked) */
@@ -246,9 +245,13 @@ struct PeerGetMessage
246 /** 245 /**
247 * 246 *
248 */ 247 */
249 enum current_destination_type dest_type; 248 enum current_destination_type current_dest_type;
250 249
251 /** 250 /**
251 * Unique identifier of the request.
252 */
253 uint64_t request_id;
254 /**
252 * When does the content expire? 255 * When does the content expire?
253 */ 256 */
254 struct GNUNET_TIME_AbsoluteNBO expiration_time; 257 struct GNUNET_TIME_AbsoluteNBO expiration_time;
@@ -527,6 +530,11 @@ struct FriendInfo
527 struct GNUNET_PeerIdentity id; 530 struct GNUNET_PeerIdentity id;
528 531
529 /** 532 /**
533 * Number of trail of which this friend is the first hop.
534 */
535 unsigned int trail_links;
536
537 /**
530 * Count of outstanding messages for this friend. 538 * Count of outstanding messages for this friend.
531 */ 539 */
532 unsigned int pending_count; 540 unsigned int pending_count;
@@ -632,11 +640,6 @@ static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
632static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap; 640static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap;
633 641
634/** 642/**
635 * Handle to ATS.
636 */
637static struct GNUNET_ATS_PerformanceHandle *atsAPI;
638
639/**
640 * Handle to CORE. 643 * Handle to CORE.
641 */ 644 */
642static struct GNUNET_CORE_Handle *core_api; 645static struct GNUNET_CORE_Handle *core_api;
@@ -806,8 +809,12 @@ GDS_NEIGHBOURS_send_trail_setup (struct GNUNET_PeerIdentity *source_peer,
806 tsm->trail_length = htonl (trail_length); 809 tsm->trail_length = htonl (trail_length);
807 tsm->finger_map_index = htonl (finger_map_index); 810 tsm->finger_map_index = htonl (finger_map_index);
808 811
809 peer_list = (struct GNUNET_PeerIdentity *) &tsm[1]; 812 if (trail_peer_list != NULL)
810 memcpy (peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity)); 813 {
814 peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
815 memcpy (peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
816 }
817
811 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); 818 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
812 target_friend->pending_count++; 819 target_friend->pending_count++;
813 process_friend_queue (target_friend); 820 process_friend_queue (target_friend);
@@ -822,8 +829,7 @@ GDS_NEIGHBOURS_send_trail_setup (struct GNUNET_PeerIdentity *source_peer,
822 * @param target_friend Friend to which this message should be forwarded. 829 * @param target_friend Friend to which this message should be forwarded.
823 * @param trail_length Numbers of peers in the trail. 830 * @param trail_length Numbers of peers in the trail.
824 * @param trail_peer_list Peers which are part of the trail from source to destination. 831 * @param trail_peer_list Peers which are part of the trail from source to destination.
825 * @param current_trail_index Index in the trial list at which receiving peer should 832 * @param current_trail_index Index at which sender of this message is located.
826 * read the next element.
827 * @param finger_map_index Index in finger peer map 833 * @param finger_map_index Index in finger peer map
828 */ 834 */
829void 835void
@@ -1059,6 +1065,12 @@ GDS_NEIGHBOURS_send_notify_new_successor (struct GNUNET_PeerIdentity *source_pee
1059 1065
1060 1066
1061/** 1067/**
1068 * FIXME: Optimizaiton Once the basic code is running. Add the optimization
1069 * where you check if the threshold on number of links that should go through
1070 * a particular friend has crossed. If yes then again choose a different
1071 * friend. Important that the new friend chosen should be different. How to
1072 * ensure this? This is an important optimization as without this one x-vine
1073 * is actually not a sybil tolerant DHT.
1062 * Randomly choose one of your friends from the friends_peer map 1074 * Randomly choose one of your friends from the friends_peer map
1063 * @return Friend 1075 * @return Friend
1064 */ 1076 */
@@ -1073,14 +1085,9 @@ select_random_friend()
1073 struct FriendInfo *friend; 1085 struct FriendInfo *friend;
1074 1086
1075 current_size = GNUNET_CONTAINER_multipeermap_size (friend_peermap); 1087 current_size = GNUNET_CONTAINER_multipeermap_size (friend_peermap);
1076
1077 /* Element stored at this index in friend_peermap should be selected friend. */
1078 index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size); 1088 index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size);
1079
1080 /* Create an iterator for friend_peermap. */
1081 iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap); 1089 iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1082 1090
1083 /* Set the position of iterator to index. */
1084 while(j < (*index)) 1091 while(j < (*index))
1085 { 1092 {
1086 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL)) 1093 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL))
@@ -1091,13 +1098,10 @@ select_random_friend()
1091 return NULL; 1098 return NULL;
1092 } 1099 }
1093 1100
1094
1095 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend)) 1101 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend))
1096 {
1097 return friend; 1102 return friend;
1098 } 1103 else
1099 1104 return NULL;
1100 return NULL;
1101} 1105}
1102 1106
1103 1107
@@ -1112,9 +1116,7 @@ compute_finger_identity()
1112 uint64_t *finger_identity64; 1116 uint64_t *finger_identity64;
1113 1117
1114 finger_identity64 = GNUNET_malloc (sizeof (uint64_t)); 1118 finger_identity64 = GNUNET_malloc (sizeof (uint64_t));
1115
1116 memcpy (&my_id64, &my_identity, sizeof (uint64_t)); 1119 memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1117
1118 /*FIXME: Do we need a mod finger = ((my_id + pow(2, finger_index)) mod (pow (2, MAX_FINGERS))*/ 1120 /*FIXME: Do we need a mod finger = ((my_id + pow(2, finger_index)) mod (pow (2, MAX_FINGERS))*/
1119 *finger_identity64 = (my_id64 + (unsigned long) pow (2,current_finger_index)); 1121 *finger_identity64 = (my_id64 + (unsigned long) pow (2,current_finger_index));
1120 1122
@@ -1162,6 +1164,7 @@ send_verify_successor_message (void *cls,
1162 unsigned int finger_index; 1164 unsigned int finger_index;
1163 unsigned int i; 1165 unsigned int i;
1164 int flag = 0; 1166 int flag = 0;
1167
1165 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 1168 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1166 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++) 1169 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1167 { 1170 {
@@ -1181,7 +1184,7 @@ send_verify_successor_message (void *cls,
1181 goto send_new_request; 1184 goto send_new_request;
1182 1185
1183 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->trail_length); 1186 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->trail_length);
1184 1187
1185 struct TrailPeerList *iterate; 1188 struct TrailPeerList *iterate;
1186 iterate = finger->head; 1189 iterate = finger->head;
1187 i = 0; 1190 i = 0;
@@ -1193,10 +1196,11 @@ send_verify_successor_message (void *cls,
1193 } 1196 }
1194 1197
1195 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 1198 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1196 memcpy (next_hop, &peer_list[1], sizeof (struct GNUNET_PeerIdentity)); 1199 memcpy (next_hop, &peer_list[0], sizeof (struct GNUNET_PeerIdentity));
1197 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 1200 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
1198 finger_trail_current_index = 2; 1201 finger_trail_current_index = 0;
1199 1202
1203
1200 GDS_NEIGHBOURS_send_verify_successor (&my_identity, 1204 GDS_NEIGHBOURS_send_verify_successor (&my_identity,
1201 &(finger->finger_identity), 1205 &(finger->finger_identity),
1202 target_friend, 1206 target_friend,
@@ -1233,14 +1237,11 @@ send_find_finger_trail_message (void *cls,
1233{ 1237{
1234 struct FriendInfo *target_friend; 1238 struct FriendInfo *target_friend;
1235 struct GNUNET_TIME_Relative next_send_time; 1239 struct GNUNET_TIME_Relative next_send_time;
1236 struct GNUNET_PeerIdentity *peer_list;
1237 uint64_t *finger_identity; 1240 uint64_t *finger_identity;
1238 unsigned int finger_map_index; 1241 unsigned int finger_map_index;
1239 1242
1240 if (1 == current_finger_index) 1243 if (1 == current_finger_index)
1241 { 1244 {
1242 /* We have started the process to find the successor. We should search
1243 for our predecessor. */
1244 finger_identity = compute_predecessor_identity(); 1245 finger_identity = compute_predecessor_identity();
1245 goto select_friend; 1246 goto select_friend;
1246 } 1247 }
@@ -1250,27 +1251,20 @@ send_find_finger_trail_message (void *cls,
1250 } 1251 }
1251 1252
1252 select_friend: 1253 select_friend:
1254 /* FIXME: Here should we choose randomly or not. */
1253 target_friend = select_random_friend(); 1255 target_friend = select_random_friend();
1254 1256
1255
1256 finger_map_index = current_finger_index; 1257 finger_map_index = current_finger_index;
1257 current_finger_index = ( current_finger_index + 1) % MAX_FINGERS; 1258 current_finger_index = ( current_finger_index + 1) % MAX_FINGERS;
1258 1259
1259 /* We found a friend.*/
1260 if(NULL != target_friend) 1260 if(NULL != target_friend)
1261 { 1261 {
1262 /* Add yourself and selected friend in the trail list. */
1263 unsigned int trail_length = 2;
1264 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length);
1265 memcpy (&peer_list[0], &(my_identity), sizeof (struct GNUNET_PeerIdentity));
1266 memcpy (&peer_list[1], &(target_friend->id), sizeof (struct GNUNET_PeerIdentity));
1267
1268 GDS_NEIGHBOURS_send_trail_setup (&my_identity, *finger_identity, &(target_friend->id), 1262 GDS_NEIGHBOURS_send_trail_setup (&my_identity, *finger_identity, &(target_friend->id),
1269 target_friend, trail_length, peer_list, 1263 target_friend, 0, NULL,
1270 finger_map_index, FRIEND); 1264 finger_map_index, FRIEND);
1271 } 1265 }
1272 1266
1273 /* FIXME: Should we be using current_finger_index to generate random interval.*/ 1267 /* FIXME: How to decide the correct interval? */
1274 next_send_time.rel_value_us = 1268 next_send_time.rel_value_us =
1275 DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us + 1269 DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1276 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, 1270 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
@@ -1396,26 +1390,91 @@ core_init (void *cls,
1396{ 1390{
1397 my_identity = *identity; 1391 my_identity = *identity;
1398 1392
1393#if 0
1394 /* SUPU TEST CODE */
1395 struct GNUNET_PeerIdentity *print_peer;
1396 print_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1397 memcpy (print_peer, &my_identity, sizeof (struct GNUNET_PeerIdentity));
1398 FPRINTF (stderr,_("\nSUPU %s, %s, %d,my_identity = %s"),
1399 __FILE__, __func__,__LINE__, GNUNET_i2s (print_peer));
1400 /* SUPU TEST CODE ENDS */
1401#endif
1399} 1402}
1400 1403
1401 1404
1405/**
1406 *
1407 * @param destination_peer
1408 * @param existing_trail
1409 * @param trail_length
1410 * @return
1411 */
1412static struct GNUNET_PeerIdentity *
1413invert_trail_list (struct GNUNET_PeerIdentity *destination_peer,
1414 struct GNUNET_PeerIdentity *existing_trail,
1415 unsigned int trail_length)
1416{
1417 int i;
1418 int j;
1419 struct GNUNET_PeerIdentity *new_trail;
1420
1421 j = 0;
1422 new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length);
1423
1424 if (trail_length > 1)
1425 {
1426 i = trail_length - 2;
1427 while (i >= 0 )
1428 {
1429 memcpy( &new_trail[j], &existing_trail[i], sizeof (struct GNUNET_PeerIdentity));
1430 i--;
1431 j++;
1432 }
1433 }
1434 memcpy (&new_trail[j], destination_peer, sizeof(struct GNUNET_PeerIdentity));
1435
1436 return new_trail;
1437}
1402 1438
1403 1439
1440/**
1441 *
1442 * @param existing_finger
1443 * @param new_finger
1444 * @return
1445 */
1446#if 0
1447static int
1448compare_finger_identity (struct GNUNET_PeerIdentity *existing_finger,
1449 struct GNUNET_PeerIdentity *new_finger)
1450{
1451 int ret;
1452 ret = (existing_finger > new_finger) ? 1 :
1453 (existing_finger == new_finger) ? 0 : -1;
1454 return ret;
1455}
1456#endif
1404 1457
1405/** 1458/**
1406 * FIXME: When we add a successor or predecessor should we check the entry in 1459 * FIXME: Not sure of the logic to find the correct predecessor.
1407 * finger map index. If we don't replace the old entry then should we notify 1460 * Given two finger identities, find the closest predecessor.
1408 * peer which think it is our predecessor or successor. Or will send verify 1461 * @param existing_predecessor
1409 * successor message will handle this case on its own. 1462 * @param new_predecessor
1410 * * FIXME: For redundant routing, we may start looking for different 1463 * @return
1411 * paths to reach to same finger. So, in send_find_finger, we are starting 1464 */
1412 * the search for trail to a finger, even if we already have found trail to 1465#if 0
1413 * reach to it. There are several reasons for doing so 1466static int
1414 * 1. We may reach to a closer successor than we have at the moment. So, we 1467compare_predecessor(struct GNUNET_PeerIdentity *existing_predecessor,
1415 * should keep looking for the successor. 1468 struct GNUNET_PeerIdentity *new_predecessor)
1416 * 2. We may reach to the same successor but through a shorter path. 1469{
1417 * 3. As I don't know how keys are distributed and how put/get will react 1470 int ret;
1418 * because of this, I have to think further before implementing it. 1471 ret = (existing_predecessor < new_predecessor) ? 1 :
1472 (existing_predecessor == new_predecessor) ? 0 : -1;
1473 return ret;
1474}
1475#endif
1476
1477/*
1419 * Add an entry in finger table. 1478 * Add an entry in finger table.
1420 * Add an entry into finger table 1479 * Add an entry into finger table
1421 * @param finger_identity Peer identity of finger 1480 * @param finger_identity Peer identity of finger
@@ -1430,14 +1489,17 @@ void finger_table_add (struct GNUNET_PeerIdentity *finger_identity,
1430 unsigned int finger_map_index) 1489 unsigned int finger_map_index)
1431{ 1490{
1432 struct FingerInfo *new_finger_entry; 1491 struct FingerInfo *new_finger_entry;
1492 int i;
1493#if 0
1433 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; 1494 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1434 struct GNUNET_PeerIdentity key_ret; 1495 struct GNUNET_PeerIdentity key_ret;
1435 struct FingerInfo *existing_finger; 1496 struct FingerInfo *existing_finger;
1436 int finger_index; 1497 int finger_index;
1437 int i; 1498 int i;
1499
1438 1500
1439 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 1501 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
1440 1502
1441 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++) 1503 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1442 { 1504 {
1443 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret, 1505 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
@@ -1449,40 +1511,47 @@ void finger_table_add (struct GNUNET_PeerIdentity *finger_identity,
1449 /* Check if the finger entry are same. */ 1511 /* Check if the finger entry are same. */
1450 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),finger_identity)) 1512 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),finger_identity))
1451 { 1513 {
1452 /* Compare the trail length. */ 1514 FPRINTF (stderr,_("\nSUPU %s, %s, %d"), __FILE__, __func__,__LINE__);
1453 if ((trail_length == existing_finger->trail_length)|| 1515 goto add_new_entry;
1454 (trail_length > existing_finger->trail_length)) 1516 }
1517 else
1518 {
1519 /* FIXME: here you should have something better to check which finger
1520 is closer one. */
1521 int ret;
1522 if (finger_map_index == 1)
1455 { 1523 {
1456 return; 1524 FPRINTF (stderr,_("\nSUPU %s, %s, %d"), __FILE__, __func__,__LINE__);
1525 ret = compare_predecessor (&(existing_finger->finger_identity),
1526 finger_identity);
1457 } 1527 }
1458 else if (trail_length < existing_finger->trail_length) 1528 else
1459 { 1529 {
1460 /* FIXME: As an optimization, when you add limit on trail length 1530 FPRINTF (stderr,_("\nSUPU %s, %s, %d"), __FILE__, __func__,__LINE__);
1461 going through a particular friend, then check if the friend to 1531 ret = compare_finger_identity (&(existing_finger->finger_identity),
1462 reach the two trails are same or not. If not then choose one 1532 finger_identity);
1463 whose threshold value has not yet reached. Also, think about 1533 }
1464 redundant routing, where you want to keep multiple paths 1534 if (ret > 0)
1465 to reach to the same finger. In that case you should allow multiple 1535 {
1466 entries with same finger identity. */ 1536 FPRINTF (stderr,_("\nSUPU %s, %s, %d"), __FILE__, __func__,__LINE__);
1467 if ( GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove (finger_peermap, 1537 GNUNET_assert (GNUNET_YES ==
1468 &(existing_finger->finger_identity), 1538 GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
1469 existing_finger)) 1539 &(existing_finger->finger_identity),
1470 { 1540 existing_finger));
1471 goto add_new_entry; 1541 goto add_new_entry;
1472 } 1542 }
1543 else
1544 {
1545 FPRINTF (stderr,_("\nSUPU %s, %s, %d"), __FILE__, __func__,__LINE__);
1546 return;
1473 } 1547 }
1474 }
1475 else
1476 {
1477 /* FIXME: Here you are if you got different finger identity then one
1478 you already have at that index. Then you should choose the
1479 one which is closest. */
1480 } 1548 }
1481 } 1549 }
1482 } 1550 }
1483 } 1551 }
1484 1552
1485 add_new_entry: 1553 add_new_entry:
1554#endif
1486 new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo)); 1555 new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo));
1487 memcpy (&(new_finger_entry->finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity)); 1556 memcpy (&(new_finger_entry->finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity));
1488 1557
@@ -1503,12 +1572,14 @@ void finger_table_add (struct GNUNET_PeerIdentity *finger_identity,
1503 new_finger_entry->trail_length = trail_length; 1572 new_finger_entry->trail_length = trail_length;
1504 1573
1505 /* FIXME: Here we are keeping multiple hashmap option so that there are 1574 /* FIXME: Here we are keeping multiple hashmap option so that there are
1506 multiple routes to reach to same finger, redundant routing. */ 1575 multiple routes to reach to same finger, redundant routing.
1576 * Also same peers could be our fingers for different finger map index */
1507 GNUNET_assert (GNUNET_OK == 1577 GNUNET_assert (GNUNET_OK ==
1508 GNUNET_CONTAINER_multipeermap_put (finger_peermap, 1578 GNUNET_CONTAINER_multipeermap_put (finger_peermap,
1509 &(new_finger_entry->finger_identity), 1579 &(new_finger_entry->finger_identity),
1510 new_finger_entry, 1580 new_finger_entry,
1511 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 1581 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); /* Fixme: change to multiple */
1582
1512 1583
1513 if (1 == GNUNET_CONTAINER_multipeermap_size (finger_peermap) 1584 if (1 == GNUNET_CONTAINER_multipeermap_size (finger_peermap)
1514 && (new_finger_entry->finger_map_index!= 1)) 1585 && (new_finger_entry->finger_map_index!= 1))
@@ -1688,7 +1759,7 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
1688 struct TrailPeerList *iterator; 1759 struct TrailPeerList *iterator;
1689 iterator = GNUNET_malloc (sizeof (struct TrailPeerList)); 1760 iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
1690 finger = successor->data; 1761 finger = successor->data;
1691 iterator = finger->head->next; 1762 iterator = finger->head;
1692 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 1763 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1693 memcpy (next_hop, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity)); 1764 memcpy (next_hop, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
1694 memcpy (current_destination, &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity)); 1765 memcpy (current_destination, &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
@@ -1701,37 +1772,34 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
1701 } 1772 }
1702} 1773}
1703 1774
1704#if 0
1705static void
1706replicate_put()
1707{
1708 /* In this function, you should find 'r' (r = desired replication level) successors
1709 and send put message to all of these r successors. Now, I really don't know
1710 if in case of node failure it will be able to find data. Or if we start with
1711 a random peer id, do we even reach to correct successor ever in case of
1712 get. */
1713}
1714#endif
1715 1775
1716/** 1776/**
1717 * 1777 * FIXME:
1718 * @param source_peer 1778 * 1. Do we have an expiration time for get request? Yes but I don't know its
1719 * @param get_path 1779 * use case and how to handle it
1720 * @param get_path_length 1780 * Send a get message to selected target friend. If target friend in NULL,
1721 * @param key 1781 * then search for a target friend.
1782 * @param request_id Unique ID identifying this request
1783 * @param source_peer Peer which started get request
1784 * @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
1786 * @param key Key key for the content
1787 * @param target_peer Next peer to forward the message to.
1788 * @param current_destination Peer which will get this message.
1789 * @param current_dest_type Type of current destination can be either FRIEND or FINGER
1722 */ 1790 */
1723void 1791void
1724GDS_NEIGHBOURS_handle_get (struct GNUNET_PeerIdentity *source_peer, 1792GDS_NEIGHBOURS_handle_get (struct GNUNET_PeerIdentity *source_peer,
1725 struct GNUNET_PeerIdentity *get_path, 1793 struct GNUNET_PeerIdentity *get_peer_path,
1726 unsigned int get_path_length, 1794 unsigned int get_path_length,
1727 struct GNUNET_HashCode *key, 1795 struct GNUNET_HashCode *key,
1728 struct GNUNET_PeerIdentity *target_peer, 1796 struct GNUNET_PeerIdentity *target_peer,
1729 struct GNUNET_PeerIdentity *current_destination, 1797 struct GNUNET_PeerIdentity *current_destination,
1730 enum current_destination_type *type) 1798 enum current_destination_type *current_dest_type)
1731{ 1799{
1732 struct PeerGetMessage *get_msg; 1800 struct PeerGetMessage *get_request;
1733 struct P2PPendingMessage *pending; 1801 struct P2PPendingMessage *pending;
1734 struct GNUNET_PeerIdentity *gp; 1802 struct GNUNET_PeerIdentity *get_path;
1735 struct FriendInfo *target_friend; 1803 struct FriendInfo *target_friend;
1736 uint64_t key_value; 1804 uint64_t key_value;
1737 size_t msize; 1805 size_t msize;
@@ -1747,27 +1815,30 @@ GDS_NEIGHBOURS_handle_get (struct GNUNET_PeerIdentity *source_peer,
1747 1815
1748 memcpy (&key_value, key, sizeof (uint64_t)); 1816 memcpy (&key_value, key, sizeof (uint64_t));
1749 1817
1818 /* FIXME: Is this correct comparison? */
1750 if (NULL == target_peer) 1819 if (NULL == target_peer)
1751 { 1820 {
1752 /* This is the first call made from client file. */ 1821 /* This is the first call made from client file. */
1753 struct GNUNET_PeerIdentity *next_hop; 1822 struct GNUNET_PeerIdentity *next_hop;
1754 next_hop = find_successor (key_value, current_destination, type); 1823 next_hop = find_successor (key_value, current_destination, current_dest_type);
1755 1824
1756 if (*type == MY_ID) 1825 if (*current_dest_type == MY_ID)
1757 { 1826 {
1758 struct GNUNET_PeerIdentity *destination_peer; 1827 struct GNUNET_PeerIdentity *destination_peer;
1759 int current_path_index; 1828 get_path = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1760 1829 memcpy (get_path, &my_identity, sizeof (struct GNUNET_PeerIdentity));
1761 /* FIXME: You enter in this part of code only if the call is made from the 1830 get_path_length = 1;
1762 client file. And in client file you already have done the datacache_get.
1763 So, ideally you don't need it. Remove it after checking. */
1764 if (get_path_length != 1)
1765 current_path_index = get_path_length - 2;
1766 destination_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 1831 destination_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1767 memcpy (destination_peer, source_peer, sizeof (struct GNUNET_PeerIdentity)); 1832 memcpy (destination_peer, source_peer, sizeof (struct GNUNET_PeerIdentity));
1768 /* I am the final destination, then call GDS_NEIGHBOURS_send_get_result.*/ 1833 /* FIXME: We enter in this part of code only when this is our first
1834 call from client file. In client file we already have done datacache_get
1835 and if we already have the result. So, ideally code should never reach
1836 here. Remove it after verifying. */
1837 /* FIXME: Call datacache_get but remove after verified above thing. */
1769 GDS_NEIGHBOURS_send_get_result (&my_identity,get_path, get_path_length, 1838 GDS_NEIGHBOURS_send_get_result (&my_identity,get_path, get_path_length,
1770 destination_peer, current_path_index); 1839 key,destination_peer, 0,
1840 NULL,0,NULL);
1841
1771 return; 1842 return;
1772 } 1843 }
1773 else 1844 else
@@ -1782,18 +1853,18 @@ GDS_NEIGHBOURS_handle_get (struct GNUNET_PeerIdentity *source_peer,
1782 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 1853 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1783 pending->importance = 0; /* FIXME */ 1854 pending->importance = 0; /* FIXME */
1784 /* FIXME: Do we have an expiration time for get request */ 1855 /* FIXME: Do we have an expiration time for get request */
1785 get_msg = (struct PeerGetMessage *) &pending[1]; 1856 get_request = (struct PeerGetMessage *) &pending[1];
1786 pending->msg = &get_msg->header; 1857 pending->msg = &get_request->header;
1787 get_msg->header.size = htons (msize); 1858 get_request->header.size = htons (msize);
1788 get_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET); 1859 get_request->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET);
1789 get_msg->get_path_length = htonl (get_path_length); 1860 get_request->get_path_length = htonl (get_path_length);
1790 get_msg->key = *key; 1861 get_request->key = *key;
1791 memcpy (&(get_msg->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); 1862
1792 memcpy (&(get_msg->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity)); 1863 memcpy (&(get_request->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1793 get_msg->dest_type = htonl (*type); 1864 memcpy (&(get_request->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
1794 1865 get_request->current_dest_type = htonl (*current_dest_type);
1795 gp = (struct GNUNET_PeerIdentity *) &get_msg[1]; 1866 get_path = (struct GNUNET_PeerIdentity *) &get_request[1];
1796 memcpy (gp, get_path, get_path_length * sizeof (struct GNUNET_PeerIdentity)); 1867 memcpy (get_path, get_peer_path, get_path_length * sizeof (struct GNUNET_PeerIdentity));
1797 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); 1868 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1798 target_friend->pending_count++; 1869 target_friend->pending_count++;
1799 process_friend_queue (target_friend); 1870 process_friend_queue (target_friend);
@@ -1826,12 +1897,12 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1826 uint32_t desired_replication_level, 1897 uint32_t desired_replication_level,
1827 struct GNUNET_TIME_Absolute expiration_time, 1898 struct GNUNET_TIME_Absolute expiration_time,
1828 uint32_t hop_count, 1899 uint32_t hop_count,
1829 struct GNUNET_HashCode *key, 1900 const struct GNUNET_HashCode *key,
1830 unsigned int put_path_length, 1901 unsigned int put_path_length,
1831 struct GNUNET_PeerIdentity *put_path, 1902 struct GNUNET_PeerIdentity *put_path,
1832 const void *data, size_t data_size, 1903 const void *data, size_t data_size,
1833 struct GNUNET_PeerIdentity *current_destination, 1904 struct GNUNET_PeerIdentity *current_destination,
1834 enum current_destination_type *dest_type, 1905 enum current_destination_type dest_type,
1835 struct GNUNET_PeerIdentity *target_peer) 1906 struct GNUNET_PeerIdentity *target_peer)
1836{ 1907{
1837 struct PeerPutMessage *ppm; 1908 struct PeerPutMessage *ppm;
@@ -1857,14 +1928,18 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1857 } 1928 }
1858 1929
1859 memcpy (&key_value, key, sizeof (uint64_t)); 1930 memcpy (&key_value, key, sizeof (uint64_t));
1931 struct GNUNET_PeerIdentity *current_dest;
1932 current_dest = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1860 if (target_peer == NULL) 1933 if (target_peer == NULL)
1861 { 1934 {
1862 /* This is the first time the call has been made from handle_dht_local_put. 1935 /* This is the first time the call has been made from handle_dht_local_put.
1863 So, you need to search for the next peer to send this message to. */ 1936 So, you need to search for the next peer to send this message to. */
1864 struct GNUNET_PeerIdentity *next_hop; 1937 struct GNUNET_PeerIdentity *next_hop;
1865 next_hop = find_successor (key_value, current_destination, dest_type); 1938
1939 next_hop = find_successor (key_value, current_dest, &dest_type);
1940
1866 1941
1867 if (*dest_type == MY_ID) 1942 if (dest_type == MY_ID)
1868 { 1943 {
1869 /* FIXME: How do we handle different block types? */ 1944 /* FIXME: How do we handle different block types? */
1870 /* FIXME: Here depending on the replication level choose 'r' successors 1945 /* FIXME: Here depending on the replication level choose 'r' successors
@@ -1896,8 +1971,11 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1896 ppm->desired_replication_level = htonl (desired_replication_level); 1971 ppm->desired_replication_level = htonl (desired_replication_level);
1897 ppm->put_path_length = htonl (put_path_length); 1972 ppm->put_path_length = htonl (put_path_length);
1898 ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time); 1973 ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
1899 memcpy (&(ppm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity)); 1974 if (current_destination != NULL)
1900 ppm->current_destination_type = htonl (*dest_type); 1975 memcpy (&(ppm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
1976 else
1977 memcpy (&(ppm->current_destination), current_dest, sizeof (struct GNUNET_PeerIdentity));
1978 ppm->current_destination_type = htonl (dest_type);
1901 ppm->key = *key; 1979 ppm->key = *key;
1902 1980
1903 pp = (struct GNUNET_PeerIdentity *) &ppm[1]; 1981 pp = (struct GNUNET_PeerIdentity *) &ppm[1];
@@ -1911,48 +1989,145 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1911 1989
1912 1990
1913/** 1991/**
1914 * 1992 * Send get result back to requesting client.
1915 * @param source_peer 1993 * @param source_peer
1916 * @param get_path 1994 * @param get_path
1995 * @param target_friend
1917 * @param get_path_length 1996 * @param get_path_length
1997 * @param key
1918 * @param destination_peer 1998 * @param destination_peer
1999 * @param current_path_index
2000 * @param data
2001 * @param data_size
1919 */ 2002 */
1920void 2003void
1921GDS_NEIGHBOURS_send_get_result (struct GNUNET_PeerIdentity *source_peer, 2004GDS_NEIGHBOURS_send_get_result (struct GNUNET_PeerIdentity *source_peer,
1922 struct GNUNET_PeerIdentity *get_path, 2005 struct GNUNET_PeerIdentity *get_path,
1923 unsigned int get_path_length, 2006 unsigned int get_path_length,
2007 struct GNUNET_HashCode *key,
1924 struct GNUNET_PeerIdentity *destination_peer, 2008 struct GNUNET_PeerIdentity *destination_peer,
1925 unsigned int current_path_index) 2009 unsigned int current_path_index,
2010 const void *data, size_t data_size,
2011 struct GNUNET_PeerIdentity *next_hop)
1926{ 2012{
1927 /* Add get_result into pending message and send the data to target friend. */ 2013 /* Add get_result into pending message and send the data to target friend.
1928#if 0 2014 make a call GDS_CLIENTS_process_get_result() with all the fields. */
1929 struct PeerGetResultMessage *get_result; 2015 struct PeerGetResultMessage *get_result;
2016 struct GNUNET_PeerIdentity *get_result_path;
1930 struct P2PPendingMessage *pending; 2017 struct P2PPendingMessage *pending;
2018 struct FriendInfo *target_friend;
1931 size_t msize; 2019 size_t msize;
1932 2020
1933 msize = (get_path_length * sizeof (struct GNUNET_PeerIdentity)) + 2021 msize = get_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size +
1934 sizeof (struct PeerGetResultMessage); 2022 sizeof (struct PeerPutMessage);
1935 2023
1936 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 2024 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1937 { 2025 {
1938 GNUNET_break (0); 2026 GNUNET_break (0);
1939 return; 2027 return;
1940 } 2028 }
1941 2029
1942#endif 2030 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2031 pending->importance = 0; /* FIXME */
2032 /* FIXME: Should we add an expiration time like in put message. */
2033 get_result = (struct PeerGetResultMessage *)&pending[1];
2034 pending->msg = &get_result->header;
2035 get_result->header.size = htons (msize);
2036 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;
2040 get_result->key = *key;
2041
2042 get_result_path = (struct GNUNET_PeerIdentity *)&get_result[1];
2043 memcpy (get_result_path, get_path,
2044 sizeof (struct GNUNET_PeerIdentity) * get_path_length);
2045 memcpy (&get_result_path[get_path_length], data, data_size);
2046
2047 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2048 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2049 target_friend->pending_count++;
2050 process_friend_queue (target_friend);
1943} 2051}
1944 2052
1945 2053
1946/** 2054/**
1947 * 2055 *
2056 * @param cls
2057 * @param peer
2058 * @param message
1948 * @return 2059 * @return
1949 */ 2060 */
1950static int 2061static int
1951handle_dht_p2p_get_result () 2062handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
2063 const struct GNUNET_MessageHeader *message)
1952{ 2064{
1953 /* If you are the source, go back to the client file and there search for 2065 /* If you are the source, go back to the client file and there search for
1954 the requesting client and send back the result. */ 2066 the requesting client and send back the result. */
1955 return GNUNET_YES; 2067 struct PeerGetResultMessage *get_result;
2068 struct GNUNET_PeerIdentity *get_path;
2069 void *payload;
2070 size_t payload_size;
2071 size_t msize;
2072 unsigned int getlen;
2073 int current_path_index;
2074
2075 msize = ntohs (message->size);
2076 if (msize < sizeof (struct PeerGetResultMessage))
2077 {
2078 GNUNET_break_op (0);
2079 return GNUNET_YES;
2080 }
2081
2082 get_result = (struct PeerGetResultMessage *)message;
2083 getlen = ntohl (get_result->get_path_length);
2084
2085 if ((msize <
2086 sizeof (struct PeerGetResultMessage) +
2087 getlen * sizeof (struct GNUNET_PeerIdentity)) ||
2088 (getlen >
2089 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2090 {
2091 GNUNET_break_op (0);
2092 return GNUNET_YES;
2093 }
2094
2095 get_path = (struct GNUNET_PeerIdentity *) &get_result[1];
2096 payload = &get_path[getlen];
2097 payload_size = msize - (sizeof (struct PeerGetResultMessage) +
2098 getlen * sizeof (struct GNUNET_PeerIdentity));
2099 current_path_index = ntohl (get_result->current_path_index);
2100
2101 /* Here you just have to check if you are the destination or not if not
2102 then read the next peer and send the message. */
2103 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(get_result->destination_peer))))
2104 {
2105 /* I am the destination. Call the function in client file.
2106 * FIXME: Here I don't know how I communicate the result back to client
2107 file. */
2108 //GDS_CLIENTS_process_get_result();
2109 return GNUNET_YES;
2110 }
2111 else
2112 {
2113 /* Read the element from the get path at trail index. set the trail index
2114 and call gds_neighbours_send_get_result.*/
2115 struct GNUNET_PeerIdentity *next_hop;
2116
2117 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2118 memcpy (next_hop, &get_path[current_path_index], sizeof (struct GNUNET_PeerIdentity));
2119
2120
2121 if (current_path_index != 0)
2122 current_path_index--;
2123
2124 GDS_NEIGHBOURS_send_get_result (&my_identity, get_path,
2125 getlen,&(get_result->key),&(get_result->destination_peer),
2126 current_path_index,
2127 payload, payload_size, next_hop);
2128 return GNUNET_YES;
2129 }
2130 return GNUNET_SYSERR;
1956} 2131}
1957 2132
1958 2133
@@ -1985,15 +2160,10 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
1985 size_t msize; 2160 size_t msize;
1986 uint32_t putlen; 2161 uint32_t putlen;
1987 2162
1988 msize = ntohs (message->size);
1989 if (msize < sizeof (struct PeerPutMessage))
1990 {
1991 GNUNET_break_op (0);
1992 return GNUNET_YES;
1993 }
1994
1995 put = (struct PeerPutMessage *) message; 2163 put = (struct PeerPutMessage *) message;
1996 putlen = ntohl (put->put_path_length); 2164 putlen = ntohl (put->put_path_length);
2165 msize = ntohs (message->size);
2166
1997 if ((msize < 2167 if ((msize <
1998 sizeof (struct PeerPutMessage) + 2168 sizeof (struct PeerPutMessage) +
1999 putlen * sizeof (struct GNUNET_PeerIdentity)) || 2169 putlen * sizeof (struct GNUNET_PeerIdentity)) ||
@@ -2090,7 +2260,7 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
2090 } 2260 }
2091 else if (current_dst_type == FINGER) 2261 else if (current_dst_type == FINGER)
2092 { 2262 {
2093 next_hop = GDS_ROUTING_search (source_peer, current_destination); 2263 next_hop = GDS_ROUTING_search (source_peer, current_destination, peer);
2094 } 2264 }
2095 2265
2096 if (current_dst_type == MY_ID) 2266 if (current_dst_type == MY_ID)
@@ -2111,7 +2281,7 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
2111 GNUNET_TIME_absolute_ntoh (put->expiration_time), 2281 GNUNET_TIME_absolute_ntoh (put->expiration_time),
2112 ntohl (put->hop_count),&put->key, putlen, 2282 ntohl (put->hop_count),&put->key, putlen,
2113 pp, payload, payload_size, 2283 pp, payload, payload_size,
2114 current_destination, &current_dst_type, next_hop); 2284 current_destination, current_dst_type, next_hop);
2115 return GNUNET_YES; 2285 return GNUNET_YES;
2116 } 2286 }
2117 return GNUNET_SYSERR; 2287 return GNUNET_SYSERR;
@@ -2136,7 +2306,7 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
2136 struct PeerGetMessage *get; 2306 struct PeerGetMessage *get;
2137 struct GNUNET_PeerIdentity *current_destination; 2307 struct GNUNET_PeerIdentity *current_destination;
2138 uint64_t key_value; 2308 uint64_t key_value;
2139 enum current_destination_type dest_type; 2309 enum current_destination_type cuurent_dest_type;
2140 struct GNUNET_PeerIdentity *next_hop; 2310 struct GNUNET_PeerIdentity *next_hop;
2141 struct GNUNET_PeerIdentity *get_path; 2311 struct GNUNET_PeerIdentity *get_path;
2142 size_t msize; 2312 size_t msize;
@@ -2167,30 +2337,38 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
2167 current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2337 current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2168 memcpy (current_destination, &(get->current_destination), sizeof (struct GNUNET_PeerIdentity)); 2338 memcpy (current_destination, &(get->current_destination), sizeof (struct GNUNET_PeerIdentity));
2169 memcpy (&key_value, &(get->key), sizeof (uint64_t)); 2339 memcpy (&key_value, &(get->key), sizeof (uint64_t));
2170 dest_type = ntohl (get->dest_type); 2340 cuurent_dest_type = ntohl (get->current_dest_type);
2171 2341
2172 if (dest_type == FRIEND) 2342 if (cuurent_dest_type == FRIEND)
2173 { 2343 {
2174 next_hop = find_successor (key_value, current_destination, &dest_type); 2344 next_hop = find_successor (key_value, current_destination, &cuurent_dest_type);
2175 } 2345 }
2176 else if (dest_type == FINGER) 2346 else if (cuurent_dest_type == FINGER)
2177 { 2347 {
2178 next_hop = GDS_ROUTING_search (&(get->source_peer), current_destination); 2348 next_hop = GDS_ROUTING_search (&(get->source_peer), current_destination, peer);
2179 } 2349 }
2180 2350
2181 if (dest_type == MY_ID) 2351 if (cuurent_dest_type == MY_ID)
2182 { 2352 {
2183 struct GNUNET_PeerIdentity *destination_peer; 2353 struct GNUNET_PeerIdentity *destination_peer;
2184 int current_path_index; 2354 //struct GNUNET_PeerIdentity *next_hop;
2355 //int current_path_index;
2185 2356
2186 /* Add yourself to the get path, increment the get length. */ 2357 /* Add yourself to the get path, increment the get length. */
2187 destination_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2358 destination_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2188 memcpy (destination_peer, &(get->source_peer), sizeof (struct GNUNET_PeerIdentity)); 2359 memcpy (destination_peer, &(get->source_peer), sizeof (struct GNUNET_PeerIdentity));
2189 current_path_index = get_length - 2; 2360 //current_path_index = get_length - 1;
2190 2361
2191 /* I am the final destination. Call GDS_NEIGHBOURS_send_get_result. */ 2362 /* I am the final destination. Call GDS_NEIGHBOURS_send_get_result.
2192 GDS_NEIGHBOURS_send_get_result (&my_identity, get_path, get_length, 2363 * FIXME: Last parameters are data and data size. First implement datacache get
2193 destination_peer, current_path_index); 2364 * and get the result and send the data. Also seach for the next friend to pass
2365 * this message to. */
2366#if 0
2367 /* FIXME: Here we should call GDS_CLIENT_handle_reply. */
2368 GDS_NEIGHBOURS_send_get_result (get->request_id, &my_identity, get_path,
2369 get_length,&(get->key), destination_peer, current_path_index,
2370 NULL, 0, next_hop);
2371#endif
2194 return GNUNET_YES; 2372 return GNUNET_YES;
2195 } 2373 }
2196 else 2374 else
@@ -2198,8 +2376,9 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
2198 /* FIXME: Add your self to the get path and increment the get length. */ 2376 /* FIXME: Add your self to the get path and increment the get length. */
2199 2377
2200 /* FIXME: Does it matter if the dest_type is friend or finger. */ 2378 /* FIXME: Does it matter if the dest_type is friend or finger. */
2201 GDS_NEIGHBOURS_handle_get (&(get->source_peer), get_path, get_length, &(get->key), 2379 GDS_NEIGHBOURS_handle_get (&(get->source_peer), get_path,
2202 next_hop, current_destination,&dest_type); 2380 get_length, &(get->key),next_hop,
2381 current_destination,&cuurent_dest_type);
2203 2382
2204 return GNUNET_YES; 2383 return GNUNET_YES;
2205 } 2384 }
@@ -2222,16 +2401,15 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
2222 struct GNUNET_PeerIdentity *next_hop; 2401 struct GNUNET_PeerIdentity *next_hop;
2223 struct FriendInfo *target_friend; 2402 struct FriendInfo *target_friend;
2224 struct GNUNET_PeerIdentity *current_destination; 2403 struct GNUNET_PeerIdentity *current_destination;
2225 struct GNUNET_PeerIdentity *next_peer;
2226 struct GNUNET_PeerIdentity *trail_peer_list; 2404 struct GNUNET_PeerIdentity *trail_peer_list;
2227 enum current_destination_type peer_type; 2405 enum current_destination_type current_dest_type;
2406 struct GNUNET_PeerIdentity *next_peer;
2228 unsigned int trail_length; 2407 unsigned int trail_length;
2229 uint32_t current_trail_index; 2408 uint32_t current_trail_index;
2230 unsigned int finger_map_index; 2409 unsigned int finger_map_index;
2231 uint64_t finger_value; 2410 uint64_t destination_finger_value;
2232 size_t msize; 2411 size_t msize;
2233 2412
2234 /* parse and validate message. */
2235 msize = ntohs (message->size); 2413 msize = ntohs (message->size);
2236 if (msize < sizeof (struct PeerTrailSetupMessage)) 2414 if (msize < sizeof (struct PeerTrailSetupMessage))
2237 { 2415 {
@@ -2242,8 +2420,7 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
2242 trail_setup = (struct PeerTrailSetupMessage *) message; 2420 trail_setup = (struct PeerTrailSetupMessage *) message;
2243 trail_length = ntohl (trail_setup->trail_length); 2421 trail_length = ntohl (trail_setup->trail_length);
2244 2422
2245 if ((msize < 2423 if ((msize < sizeof (struct PeerTrailSetupMessage) +
2246 sizeof (struct PeerTrailSetupMessage) +
2247 trail_length * sizeof (struct GNUNET_PeerIdentity)) || 2424 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2248 (trail_length > 2425 (trail_length >
2249 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) 2426 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
@@ -2252,123 +2429,118 @@ handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
2252 return GNUNET_YES; 2429 return GNUNET_YES;
2253 } 2430 }
2254 2431
2255 peer_type = ntohl (trail_setup->current_destination_type); 2432 current_dest_type = ntohl (trail_setup->current_destination_type);
2256 finger_map_index = ntohl (trail_setup->finger_map_index); 2433 finger_map_index = ntohl (trail_setup->finger_map_index);
2257 trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_setup[1]; 2434 trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_setup[1];
2258 finger_value = trail_setup->destination_finger; 2435 destination_finger_value = trail_setup->destination_finger;
2259 current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2436 current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2260 memcpy (current_destination, &(trail_setup->current_destination), sizeof (struct GNUNET_PeerIdentity)); 2437 memcpy (current_destination, &(trail_setup->current_destination), sizeof (struct GNUNET_PeerIdentity));
2261 2438
2262 if (peer_type == FRIEND) 2439 /* Find the next hop to send the packet to. */
2440 if (current_dest_type == FRIEND)
2263 { 2441 {
2264 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_setup->current_destination), 2442 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_setup->current_destination),
2265 &my_identity))) 2443 &my_identity)))
2266 { 2444 {
2267 next_hop = find_successor (finger_value, current_destination, &(peer_type)); 2445 next_hop = find_successor (destination_finger_value, current_destination, &(current_dest_type));
2268 } 2446 }
2269 else 2447 else
2270 return GNUNET_SYSERR; 2448 return GNUNET_SYSERR;
2271 } 2449 }
2272 else if (peer_type == FINGER) 2450 else if (current_dest_type == FINGER)
2273 { 2451 {
2274 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_setup->current_destination), 2452 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_setup->current_destination),
2275 &my_identity))) 2453 &my_identity)))
2276 { 2454 {
2277 next_hop = GDS_ROUTING_search (&(trail_setup->source_peer), 2455 next_hop = GDS_ROUTING_search (&(trail_setup->source_peer),
2278 &(trail_setup->current_destination)); 2456 &(trail_setup->current_destination), peer);
2279 2457 /* As an optimization, find the successor from the find successor and
2280 #if 0 2458 compare both the ids to find the closest peer. */
2281 /* This is an optimization. Uncomment when basic code is running first. */
2282 /* I am part of trail.*/
2283 struct GNUNET_PeerIdentity *next_peer_routing_table;
2284 next_peer_routing_table = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2285 next_peer_routing_table = GDS_ROUTING_search (&(trail_setup->source_peer),
2286 &(trail_setup->current_destination));
2287
2288 struct GNUNET_PeerIdentity *next_peer_find_successor;
2289 next_peer_find_successor = find_successor (&(trail_setup->destination_finger),
2290 &(trail_setup->current_destination),
2291 &(peer_type));
2292
2293 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2294 next_hop = find_closest_destination (next_peer_routing_table,
2295 next_peer_find_successor,
2296 &(trail_setup->destination_finger) );
2297 #endif
2298 } 2459 }
2299 else 2460 else
2300 { 2461 {
2301 /* I am the current_destination finger */ 2462 next_hop = find_successor (destination_finger_value, current_destination, &(current_dest_type));
2302 next_hop = find_successor (finger_value, current_destination, &(peer_type));
2303 } 2463 }
2304 } 2464 }
2465
2466 /* Add yourself to the trail list and increment the trail length. */
2467 struct GNUNET_PeerIdentity *peer_list;
2468 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * (trail_length + 1));
2469 if ( trail_length > 0)
2470 {
2471 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2472 }
2473 memcpy (&peer_list[trail_length], &my_identity, sizeof (struct GNUNET_PeerIdentity));
2474 trail_length++;
2305 2475
2306 /* If you are the next hop, then you are the final destination */ 2476 if (current_dest_type == MY_ID ||
2307 if (peer_type == MY_ID) 2477 (0 == GNUNET_CRYPTO_cmp_peer_identity(next_hop, &(trail_setup->source_peer))))
2308 { 2478 {
2309 struct GNUNET_PeerIdentity *source; 2479 struct GNUNET_PeerIdentity *source_peer;
2310 source = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2480 source_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2311 memcpy (source, &(trail_setup->source_peer), sizeof (struct GNUNET_PeerIdentity)); 2481 memcpy (source_peer, &(trail_setup->source_peer), sizeof (struct GNUNET_PeerIdentity));
2312 current_trail_index = trail_length - 2; 2482
2313 next_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2483 current_trail_index = trail_length - 1;
2314 memcpy (next_peer, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity)); 2484 next_peer= GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2485 if (current_trail_index == 0)
2486 {
2487 memcpy (next_peer, &(trail_setup->source_peer), sizeof (struct GNUNET_PeerIdentity));
2488 }
2489 else
2490 {
2491 memcpy (next_peer, &trail_peer_list[current_trail_index-1], sizeof (struct GNUNET_PeerIdentity));
2492 }
2493
2315 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_peer); 2494 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_peer);
2316 GNUNET_free (next_peer); 2495 GNUNET_free (next_peer);
2317 2496
2318 if(current_trail_index != 0)
2319 current_trail_index = current_trail_index - 1;
2320
2321 if (0 == trail_setup->finger_map_index) 2497 if (0 == trail_setup->finger_map_index)
2322 { 2498 {
2323 struct GNUNET_PeerIdentity *new_trail; 2499 struct GNUNET_PeerIdentity *new_trail_list;
2324 int i; 2500 new_trail_list = invert_trail_list (source_peer, peer_list, trail_length);
2325 int j; 2501 finger_table_add (source_peer, new_trail_list, trail_length, 1);
2326
2327 i = trail_length - 1;
2328 j = 0;
2329 new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) *
2330 trail_length);
2331 while (i > 0)
2332 {
2333 memcpy( &new_trail[j], &trail_peer_list[i], sizeof (struct GNUNET_PeerIdentity));
2334 i--;
2335 j++;
2336 }
2337 memcpy (&new_trail[j], &trail_peer_list[i], sizeof(struct GNUNET_PeerIdentity));
2338 finger_table_add (source, new_trail, trail_length, 1);
2339 } 2502 }
2340 2503
2341 GDS_NEIGHBOURS_send_trail_setup_result (&(trail_setup->source_peer), 2504 GDS_NEIGHBOURS_send_trail_setup_result (&(trail_setup->source_peer),
2342 &(my_identity), 2505 &(my_identity),
2343 target_friend, trail_length, 2506 target_friend, trail_length,
2344 trail_peer_list, current_trail_index, 2507 peer_list, current_trail_index,
2345 finger_map_index); 2508 finger_map_index);
2346 2509
2347 return GNUNET_YES; 2510 return GNUNET_YES;
2348 } 2511 }
2349 2512 else if (next_hop == NULL)
2350 /* Add next hop to list of peers. */
2351 struct GNUNET_PeerIdentity *peer_list;
2352 peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * (trail_length + 1));
2353 memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2354 memcpy (&peer_list[trail_length], next_hop, sizeof (struct GNUNET_PeerIdentity));
2355 trail_length++;
2356
2357 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2358
2359 if(peer_type == FINGER)
2360 { 2513 {
2361 GDS_ROUTING_add (&(trail_setup->source_peer), 2514 return GNUNET_SYSERR;
2362 &(trail_setup->current_destination),
2363 next_hop);
2364 } 2515 }
2516 else
2517 {
2518 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2519 if(current_dest_type == FINGER)
2520 {
2521 /* FIXME: Here it can even return err if routing entries have crossed the
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 }
2365 2535
2366 GDS_NEIGHBOURS_send_trail_setup (&(trail_setup->source_peer), 2536 GDS_NEIGHBOURS_send_trail_setup (&(trail_setup->source_peer),
2367 trail_setup->destination_finger, 2537 trail_setup->destination_finger,
2368 current_destination, target_friend, trail_length, 2538 current_destination, target_friend, trail_length,
2369 peer_list, finger_map_index, peer_type); 2539 peer_list, finger_map_index, current_dest_type);
2370 2540
2371return GNUNET_YES; 2541 return GNUNET_YES;
2542 }
2543 return GNUNET_SYSERR;
2372} 2544}
2373 2545
2374 2546
@@ -2385,7 +2557,7 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
2385{ 2557{
2386 struct PeerTrailSetupResultMessage *trail_result; 2558 struct PeerTrailSetupResultMessage *trail_result;
2387 struct GNUNET_PeerIdentity *trail_peer_list; 2559 struct GNUNET_PeerIdentity *trail_peer_list;
2388 struct GNUNET_PeerIdentity *next_peer; 2560 struct GNUNET_PeerIdentity *next_hop;
2389 struct FriendInfo *target_friend; 2561 struct FriendInfo *target_friend;
2390 unsigned int current_trail_index; 2562 unsigned int current_trail_index;
2391 unsigned int finger_map_index; 2563 unsigned int finger_map_index;
@@ -2418,45 +2590,44 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
2418 trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1]; 2590 trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1];
2419 2591
2420 if ( 0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer), 2592 if ( 0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
2421 &my_identity))) 2593 &my_identity)))
2422 { 2594 {
2423 #if 0 2595#if 0
2424 /* SUPU: Here I have removed myself from the trail before storing it in 2596 /* I don't remember why I have written this code. */
2425 th finger table - to save space, but in case of verify successor result 2597 if (finger_map_index == 1)
2426 the result trail does not contain me, and I will never get the message back. 2598 {
2427 So, keeping myself in the trail list. Think of better solution.*/ 2599 struct GNUNET_PeerIdentity *new_trail_list;
2428 struct GNUNET_PeerIdentity *finger_trail; 2600 new_trail_list = invert_trail_list (&(trail_result->finger_identity),
2429 finger_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * (trail_length - 1)); 2601 trail_peer_list, trail_length);
2430 2602 finger_table_add (&(trail_result->finger_identity), new_trail_list, trail_length,
2431 /* Copy the whole trail_peer_list except the first element into trail */ 2603 finger_map_index);
2432 unsigned int i; 2604 return GNUNET_YES;
2433 i = trail_length - 1; 2605 }
2434 while (i > 0) 2606 else
2435 { 2607 {
2436 memcpy (&finger_trail[i], &trail_peer_list[i], sizeof (struct GNUNET_PeerIdentity)); 2608#endif
2437 i--; 2609 finger_table_add (&(trail_result->finger_identity), trail_peer_list, trail_length,
2438 } 2610 finger_map_index);
2439 trail_length = trail_length -1 ; SUPU: As you removed yourself from the trail.*/ 2611
2440 #endif 2612 return GNUNET_YES;
2441 2613 //}
2442 finger_table_add (&(trail_result->finger_identity), trail_peer_list, trail_length,
2443 finger_map_index);
2444
2445 return GNUNET_YES;
2446 } 2614 }
2447 else 2615 else
2448 { 2616 {
2449 next_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2617 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2450 memcpy (next_peer, &(trail_peer_list[current_trail_index]), 2618
2451 sizeof (struct GNUNET_PeerIdentity)); 2619 current_trail_index = current_trail_index - 1;
2452 /* SUPU: here current trail index will always be greater than 0. 2620 if (current_trail_index == 0)
2453 so no need for this check here. trail index = 0, contains the final 2621 {
2454 destination, and if we are in this loop we have not yet reached the 2622 memcpy (next_hop, &(trail_result->destination_peer),sizeof (struct GNUNET_PeerIdentity));
2455 final destination. */ 2623 }
2456 current_trail_index = current_trail_index - 1; 2624 else
2625 {
2626 memcpy (next_hop, &(trail_peer_list[current_trail_index-1]),sizeof (struct GNUNET_PeerIdentity));
2627 }
2457 2628
2458 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_peer); 2629 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2459 GNUNET_free (next_peer); 2630 GNUNET_free (next_hop);
2460 2631
2461 GDS_NEIGHBOURS_send_trail_setup_result (&(trail_result->destination_peer), 2632 GDS_NEIGHBOURS_send_trail_setup_result (&(trail_result->destination_peer),
2462 &(trail_result->finger_identity), 2633 &(trail_result->finger_identity),
@@ -2471,6 +2642,38 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p
2471 2642
2472 2643
2473/** 2644/**
2645 * FIXME: Use flag in the case finger peer map does not contain predcessor
2646 * then its NULL. Ideally it should never happen.
2647 * Get my current predecessor from the finger peer map
2648 * @return Current predecessor.
2649 */
2650static struct FingerInfo *
2651get_predecessor()
2652{
2653 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2654 struct GNUNET_PeerIdentity key_ret;
2655 unsigned int finger_index;
2656 struct FingerInfo *my_predecessor;
2657
2658 /* Iterate over finger peer map and extract your predecessor. */
2659 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);
2660 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
2661 {
2662 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next
2663 (finger_iter,&key_ret,(const void **)&my_predecessor))
2664 {
2665 if(1 == my_predecessor->finger_map_index)
2666 {
2667 break;
2668 }
2669 }
2670 }
2671 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2672 return my_predecessor;
2673}
2674
2675
2676/**
2474 * Core handle for p2p verify successor messages. 2677 * Core handle for p2p verify successor messages.
2475 * @param cls closure 2678 * @param cls closure
2476 * @param message message 2679 * @param message message
@@ -2500,15 +2703,13 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee
2500 vsm = (struct PeerVerifySuccessorMessage *) message; 2703 vsm = (struct PeerVerifySuccessorMessage *) message;
2501 trail_length = ntohl (vsm->trail_length); 2704 trail_length = ntohl (vsm->trail_length);
2502 2705
2503 if ((msize < 2706 if ((msize < sizeof (struct PeerVerifySuccessorMessage) +
2504 sizeof (struct PeerVerifySuccessorMessage) + 2707 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2505 trail_length * sizeof (struct GNUNET_PeerIdentity)) || 2708 (trail_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2506 (trail_length > 2709 {
2507 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) 2710 GNUNET_break_op (0);
2508 { 2711 return GNUNET_YES;
2509 GNUNET_break_op (0); 2712 }
2510 return GNUNET_YES;
2511 }
2512 2713
2513 current_trail_index = ntohl (vsm->current_trail_index); 2714 current_trail_index = ntohl (vsm->current_trail_index);
2514 trail_peer_list = (struct GNUNET_PeerIdentity *) &vsm[1]; 2715 trail_peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
@@ -2517,80 +2718,29 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee
2517 2718
2518 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2719 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2519 2720
2520 /* SUPU: If I am the destination. */ 2721 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),&my_identity)))
2521 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),
2522 &my_identity)))
2523 { 2722 {
2524 struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2525 struct GNUNET_PeerIdentity key_ret;
2526 unsigned int finger_index;
2527 struct FingerInfo *my_predecessor; 2723 struct FingerInfo *my_predecessor;
2528 struct GNUNET_PeerIdentity *destination_peer; 2724 current_trail_index = trail_length - 1;
2529 2725 if (current_trail_index == 0)
2530 /* Iterate over finger peer map and extract your predecessor. */ 2726 memcpy (next_hop, source_peer, sizeof (struct GNUNET_PeerIdentity));
2531 finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 2727 else
2532 for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++) 2728 memcpy (next_hop, &trail_peer_list[current_trail_index-1], sizeof (struct GNUNET_PeerIdentity));
2533 {
2534 if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next
2535 (finger_iter,&key_ret,(const void **)&my_predecessor))
2536 {
2537 if(1 == my_predecessor->finger_map_index)
2538 {
2539 break;
2540 }
2541 }
2542 }
2543 GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2544 2729
2545 destination_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2546 memcpy (destination_peer, source_peer, sizeof (struct GNUNET_PeerIdentity));
2547 current_trail_index = trail_length - 2;
2548 memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
2549 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 2730 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2550 GNUNET_free (next_hop); 2731 GNUNET_free (next_hop);
2551 2732
2552 if (current_trail_index != 0) 2733 my_predecessor = get_predecessor();
2553 current_trail_index = current_trail_index - 1; 2734 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (source_peer,
2554 2735 &(my_predecessor->finger_identity))))
2555 /*SUPU: Remove this later*/
2556 struct GNUNET_PeerIdentity *predecessor;
2557 predecessor = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2558 if (NULL == my_predecessor)
2559 { 2736 {
2560 /* FIXME: Ideally my_predecessor should not be NULL. If some one sent 2737 GDS_NEIGHBOURS_send_verify_successor_result (source_peer,
2561 me a request to verify it I am the successor or not, then I would have
2562 added that peer to my_predecessor list. Check trail setup and see if
2563 you are adding predecessor when you get the request for successor. */
2564#if 0
2565 update_predecessor (source_peer, trail_peer_list, trail_length);
2566
2567 GDS_NEIGHBOURS_send_verify_successor_result (destination_peer,
2568 &(my_identity), 2738 &(my_identity),
2569 source_peer, 2739 &(my_predecessor->finger_identity),
2570 target_friend, 2740 target_friend,
2571 trail_peer_list, 2741 trail_peer_list,
2572 trail_length, 2742 trail_length,
2573 current_trail_index); 2743 current_trail_index);
2574#endif
2575 }
2576 else
2577 {
2578 /* FIXME: some times my_predecssor->finger_identity has no valid value.
2579 Check why?*/
2580 memcpy (predecessor, &(my_predecessor->finger_identity), sizeof (struct GNUNET_PeerIdentity));
2581 }
2582
2583 if (0 == (GNUNET_CRYPTO_cmp_peer_identity (source_peer,
2584 &(my_predecessor->finger_identity))))
2585 {
2586 /* SUPU: If source peer is my predecessor .*/
2587 GDS_NEIGHBOURS_send_verify_successor_result (destination_peer,
2588 &(my_identity),
2589 &(my_predecessor->finger_identity),
2590 target_friend,
2591 trail_peer_list,
2592 trail_length,
2593 current_trail_index);
2594 } 2744 }
2595 else 2745 else
2596 { 2746 {
@@ -2598,18 +2748,12 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee
2598 int new_trail_length; 2748 int new_trail_length;
2599 int i; 2749 int i;
2600 2750
2601 new_trail_length = trail_length + my_predecessor->trail_length - 1; 2751 new_trail_length = trail_length + my_predecessor->trail_length;
2602 new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) 2752 new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * new_trail_length);
2603 * new_trail_length); 2753 memcpy (new_successor_trail, trail_peer_list, (trail_length) * sizeof (struct GNUNET_PeerIdentity));
2604
2605 /* Copy the trail from source peer to me. */
2606 memcpy (new_successor_trail, trail_peer_list,
2607 (trail_length) * sizeof (struct GNUNET_PeerIdentity));
2608
2609 /* Copy the trail from me to my predecessor excluding me. */
2610 struct TrailPeerList *iterator; 2754 struct TrailPeerList *iterator;
2611 iterator = GNUNET_malloc (sizeof (struct TrailPeerList)); 2755 iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
2612 iterator = my_predecessor->head->next; 2756 iterator = my_predecessor->head;
2613 i = trail_length; 2757 i = trail_length;
2614 while (i < new_trail_length) 2758 while (i < new_trail_length)
2615 { 2759 {
@@ -2618,27 +2762,25 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee
2618 i++; 2762 i++;
2619 } 2763 }
2620 2764
2621 GDS_NEIGHBOURS_send_verify_successor_result (destination_peer, 2765 GDS_NEIGHBOURS_send_verify_successor_result (source_peer,
2622 &(my_identity), 2766 &(my_identity),
2623 &(my_predecessor->finger_identity), 2767 &(my_predecessor->finger_identity),
2624 target_friend, 2768 target_friend,
2625 new_successor_trail, 2769 new_successor_trail,
2626 new_trail_length, 2770 new_trail_length,
2627 current_trail_index); 2771 current_trail_index);
2628 } 2772 }
2629 2773
2630 } 2774 }
2631 else 2775 else
2632 { 2776 {
2633 /* If I am not the destination. */ 2777 current_trail_index = current_trail_index + 1;
2634 memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity)); 2778 memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
2635 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 2779 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2636 GNUNET_free (next_hop); 2780 GNUNET_free (next_hop);
2637 2781
2638 current_trail_index = current_trail_index + 1; 2782 GDS_NEIGHBOURS_send_verify_successor (source_peer, &(vsm->successor),target_friend,
2639 2783 trail_peer_list, trail_length, current_trail_index);
2640 GDS_NEIGHBOURS_send_verify_successor(source_peer, &(vsm->successor),target_friend,
2641 trail_peer_list, trail_length, current_trail_index);
2642 } 2784 }
2643 return GNUNET_YES; 2785 return GNUNET_YES;
2644} 2786}
@@ -2671,10 +2813,9 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity
2671 nsm = (struct PeerNotifyNewSuccessorMessage *) message; 2813 nsm = (struct PeerNotifyNewSuccessorMessage *) message;
2672 trail_length = ntohl (nsm->trail_length); 2814 trail_length = ntohl (nsm->trail_length);
2673 2815
2674 if ((msize < 2816 if ((msize < sizeof (struct PeerNotifyNewSuccessorMessage) +
2675 sizeof (struct PeerNotifyNewSuccessorMessage) + 2817 trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2676 trail_length * sizeof (struct GNUNET_PeerIdentity)) || 2818 (trail_length >
2677 (trail_length >
2678 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) 2819 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2679 { 2820 {
2680 GNUNET_break_op (0); 2821 GNUNET_break_op (0);
@@ -2684,38 +2825,25 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity
2684 current_trail_index = ntohl (nsm->current_index); 2825 current_trail_index = ntohl (nsm->current_index);
2685 trail_peer_list = (struct GNUNET_PeerIdentity *) &nsm[1]; 2826 trail_peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
2686 2827
2687 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer), 2828 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer), &my_identity)))
2688 &my_identity)))
2689 { 2829 {
2690 struct GNUNET_PeerIdentity *new_trail; 2830 struct GNUNET_PeerIdentity *new_trail;
2691 int i; 2831 new_trail = invert_trail_list (&(nsm->source_peer), trail_peer_list, trail_length);
2692 int j; 2832 finger_table_add (&(nsm->source_peer), new_trail, trail_length, 1);
2693
2694 i = trail_length - 1;
2695 j = 0;
2696 new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) *
2697 trail_length);
2698 while (i > 0)
2699 {
2700 memcpy( &new_trail[j], &trail_peer_list[i], sizeof (struct GNUNET_PeerIdentity));
2701 i--;
2702 j++;
2703 }
2704 memcpy (&new_trail[j], &trail_peer_list[i], sizeof(struct GNUNET_PeerIdentity));
2705 finger_table_add (&(nsm->source_peer), new_trail, trail_length, 1);
2706
2707 return GNUNET_YES; 2833 return GNUNET_YES;
2708 } 2834 }
2709 else 2835 else
2710 { 2836 {
2711 struct FriendInfo *target_friend; 2837 struct FriendInfo *target_friend;
2712 target_friend = GNUNET_malloc (sizeof (struct FriendInfo));
2713 struct GNUNET_PeerIdentity *next_hop; 2838 struct GNUNET_PeerIdentity *next_hop;
2839
2840 target_friend = GNUNET_malloc (sizeof (struct FriendInfo));
2714 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2841 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2842
2843 current_trail_index = current_trail_index + 1;
2715 memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity)); 2844 memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
2716 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 2845 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2717 GNUNET_free (next_hop); 2846 GNUNET_free (next_hop);
2718 current_trail_index = current_trail_index + 1;
2719 2847
2720 GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer), 2848 GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer),
2721 &(nsm->destination_peer), 2849 &(nsm->destination_peer),
@@ -2768,17 +2896,15 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti
2768 current_trail_index = ntohl (vsrm->current_index); 2896 current_trail_index = ntohl (vsrm->current_index);
2769 trail_peer_list = (struct GNUNET_PeerIdentity *) &vsrm[1]; 2897 trail_peer_list = (struct GNUNET_PeerIdentity *) &vsrm[1];
2770 2898
2771 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->destination_peer), 2899 if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->destination_peer), &(my_identity))))
2772 &(my_identity))))
2773 { 2900 {
2774 if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->my_predecessor), 2901 if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->my_predecessor), &(my_identity))))
2775 &(my_identity))))
2776 { 2902 {
2777 finger_table_add (&(vsrm->my_predecessor), trail_peer_list, trail_length, 0); 2903 finger_table_add (&(vsrm->my_predecessor), trail_peer_list, trail_length, 0);
2778 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2904 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2779 memcpy (next_hop, &trail_peer_list[1], sizeof (struct GNUNET_PeerIdentity)); 2905 memcpy (next_hop, &trail_peer_list[0], sizeof (struct GNUNET_PeerIdentity));
2780 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 2906 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2781 current_trail_index = 2; 2907 current_trail_index = 0;
2782 GNUNET_free (next_hop); 2908 GNUNET_free (next_hop);
2783 2909
2784 GDS_NEIGHBOURS_send_notify_new_successor (&my_identity, &(vsrm->my_predecessor), 2910 GDS_NEIGHBOURS_send_notify_new_successor (&my_identity, &(vsrm->my_predecessor),
@@ -2789,10 +2915,13 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti
2789 else 2915 else
2790 { 2916 {
2791 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 2917 next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2792 memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity)); 2918 current_trail_index = current_trail_index - 1;
2919 if (current_trail_index == 0)
2920 memcpy (next_hop, &(vsrm->destination_peer), sizeof (struct GNUNET_PeerIdentity));
2921 else
2922 memcpy (next_hop, &trail_peer_list[current_trail_index-1], sizeof (struct GNUNET_PeerIdentity));
2793 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 2923 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2794 GNUNET_free (next_hop); 2924 GNUNET_free (next_hop);
2795 current_trail_index = current_trail_index - 1;
2796 2925
2797 GDS_NEIGHBOURS_send_verify_successor_result (&(vsrm->destination_peer), 2926 GDS_NEIGHBOURS_send_verify_successor_result (&(vsrm->destination_peer),
2798 &(vsrm->source_successor), 2927 &(vsrm->source_successor),
@@ -2825,9 +2954,6 @@ GDS_NEIGHBOURS_init()
2825 {NULL, 0, 0} 2954 {NULL, 0, 0}
2826 }; 2955 };
2827 2956
2828
2829 /*TODO: What is ATS? Why do we need it? */
2830 atsAPI = GNUNET_ATS_performance_init (GDS_cfg, NULL, NULL);
2831 core_api = 2957 core_api =
2832 GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect, 2958 GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
2833 &handle_core_disconnect, NULL, GNUNET_NO, NULL, 2959 &handle_core_disconnect, NULL, GNUNET_NO, NULL,
@@ -2853,14 +2979,11 @@ GDS_NEIGHBOURS_done ()
2853 2979
2854 GNUNET_CORE_disconnect (core_api); 2980 GNUNET_CORE_disconnect (core_api);
2855 core_api = NULL; 2981 core_api = NULL;
2856 GNUNET_ATS_performance_done (atsAPI); 2982
2857 atsAPI = NULL;
2858
2859 GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap)); 2983 GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
2860 GNUNET_CONTAINER_multipeermap_destroy (friend_peermap); 2984 GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
2861 friend_peermap = NULL; 2985 friend_peermap = NULL;
2862 2986
2863
2864 GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (finger_peermap)); 2987 GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (finger_peermap));
2865 GNUNET_CONTAINER_multipeermap_destroy (finger_peermap); 2988 GNUNET_CONTAINER_multipeermap_destroy (finger_peermap);
2866 finger_peermap = NULL; 2989 finger_peermap = NULL;
@@ -2870,8 +2993,7 @@ GDS_NEIGHBOURS_done ()
2870 GNUNET_SCHEDULER_cancel (find_finger_trail_task); 2993 GNUNET_SCHEDULER_cancel (find_finger_trail_task);
2871 find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK; 2994 find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
2872 } 2995 }
2873 2996
2874
2875 if (GNUNET_SCHEDULER_NO_TASK != verify_successor) 2997 if (GNUNET_SCHEDULER_NO_TASK != verify_successor)
2876 { 2998 {
2877 GNUNET_SCHEDULER_cancel (verify_successor); 2999 GNUNET_SCHEDULER_cancel (verify_successor);
diff --git a/src/dht/gnunet-service-xdht_neighbours.h b/src/dht/gnunet-service-xdht_neighbours.h
index da5629ffb..8e0fce225 100644
--- a/src/dht/gnunet-service-xdht_neighbours.h
+++ b/src/dht/gnunet-service-xdht_neighbours.h
@@ -68,12 +68,12 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
68 uint32_t desired_replication_level, 68 uint32_t desired_replication_level,
69 struct GNUNET_TIME_Absolute expiration_time, 69 struct GNUNET_TIME_Absolute expiration_time,
70 uint32_t hop_count, 70 uint32_t hop_count,
71 struct GNUNET_HashCode * key, 71 const struct GNUNET_HashCode * key,
72 unsigned int put_path_length, 72 unsigned int put_path_length,
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 enum current_destination_type *dest_type, 76 enum current_destination_type dest_type,
77 struct GNUNET_PeerIdentity *target_peer_id); 77 struct GNUNET_PeerIdentity *target_peer_id);
78 78
79 79
@@ -94,18 +94,25 @@ GDS_NEIGHBOURS_handle_get (struct GNUNET_PeerIdentity *source_peer,
94 enum current_destination_type *type); 94 enum current_destination_type *type);
95 95
96/** 96/**
97 * 97 * Send get result back to requesting client.
98 * @param source_peer 98 * @param source_peer
99 * @param get_path 99 * @param get_path
100 * @param get_path_length 100 * @param get_path_length
101 * @param key
101 * @param destination_peer 102 * @param destination_peer
103 * @param current_path_index
104 * @param data
105 * @param data_size
102 */ 106 */
103void 107void
104GDS_NEIGHBOURS_send_get_result (struct GNUNET_PeerIdentity *source_peer, 108GDS_NEIGHBOURS_send_get_result (struct GNUNET_PeerIdentity *source_peer,
105 struct GNUNET_PeerIdentity *get_path, 109 struct GNUNET_PeerIdentity *get_path,
106 unsigned int get_path_length, 110 unsigned int get_path_length,
111 struct GNUNET_HashCode *key,
107 struct GNUNET_PeerIdentity *destination_peer, 112 struct GNUNET_PeerIdentity *destination_peer,
108 unsigned int current_path_index); 113 unsigned int current_path_index,
114 const void *data, size_t data_size,
115 struct GNUNET_PeerIdentity *next_peer);
109 116
110 117
111/** 118/**
diff --git a/src/dht/gnunet-service-xdht_routing.c b/src/dht/gnunet-service-xdht_routing.c
index 55ef1f4b2..f7e56c115 100644
--- a/src/dht/gnunet-service-xdht_routing.c
+++ b/src/dht/gnunet-service-xdht_routing.c
@@ -34,9 +34,12 @@
34 */ 34 */
35#define DHT_MAX_RECENT (1024 * 16) 35#define DHT_MAX_RECENT (1024 * 16)
36 36
37/**
38 * Maximum number of entries in routing table.
39 */
40#define ROUTING_TABLE_THRESHOLD 64
37 41
38/** 42/**
39 * FIXME: Do we need a field prev_hop
40 * Routing table entry . 43 * Routing table entry .
41 */ 44 */
42struct RoutingTrail 45struct RoutingTrail
@@ -56,6 +59,11 @@ struct RoutingTrail
56 */ 59 */
57 struct GNUNET_PeerIdentity next_hop; 60 struct GNUNET_PeerIdentity next_hop;
58 61
62 /**
63 * Peer just before next hop in the trail.
64 */
65 struct GNUNET_PeerIdentity prev_hop;
66
59}; 67};
60 68
61 69
@@ -66,56 +74,91 @@ static struct GNUNET_CONTAINER_MultiPeerMap *routing_table;
66 74
67 75
68/** 76/**
69 * FIXME: Change the name of variable.
70 * Ensure that everywhere in this file you are using destination as the key.
71 * Do we need prev field in routing table?
72 * Add a new entry to our routing table. 77 * Add a new entry to our routing table.
73 * @param source peer 78 * @param source peer Source of the trail.
74 * @param destintation 79 * @param destintation Destination of the trail.
75 * @param next_hop 80 * @param next_hop Next peer to forward the message to reach the destination.
81 * @return GNUNET_YES
82 * GNUNET_SYSERR If the number of routing entries crossed thershold.
76 */ 83 */
77void 84int
78GDS_ROUTING_add (struct GNUNET_PeerIdentity *source, 85GDS_ROUTING_add (struct GNUNET_PeerIdentity *source,
79 struct GNUNET_PeerIdentity *dest, 86 struct GNUNET_PeerIdentity *dest,
80 struct GNUNET_PeerIdentity *next_hop) 87 struct GNUNET_PeerIdentity *next_hop,
88 const struct GNUNET_PeerIdentity *prev_hop)
81{ 89{
82 struct RoutingTrail *new_routing_entry; 90 struct RoutingTrail *new_routing_entry;
83 91
84 /* If dest is already present in the routing table, then exit.*/ 92 if (GNUNET_CONTAINER_multipeermap_size(routing_table) > ROUTING_TABLE_THRESHOLD)
85 if (GNUNET_YES == 93 return GNUNET_SYSERR;
86 GNUNET_CONTAINER_multipeermap_contains (routing_table, dest)) 94 //FPRINTF (stderr,_("\nSUPU ROUTING ADD %s, %s, %d"),__FILE__, __func__,__LINE__);
87 {
88 GNUNET_break (0);
89 return;
90 }
91
92 new_routing_entry = GNUNET_malloc (sizeof (struct RoutingTrail)); 95 new_routing_entry = GNUNET_malloc (sizeof (struct RoutingTrail));
93 memcpy (&(new_routing_entry->source) , source, sizeof (struct GNUNET_PeerIdentity)); 96 memcpy (&(new_routing_entry->source) , source, sizeof (struct GNUNET_PeerIdentity));
94 memcpy (&(new_routing_entry->next_hop), next_hop, sizeof (struct GNUNET_PeerIdentity)); 97 memcpy (&(new_routing_entry->next_hop), next_hop, sizeof (struct GNUNET_PeerIdentity));
95 memcpy (&(new_routing_entry->destination), dest, sizeof (struct GNUNET_PeerIdentity)); 98 memcpy (&(new_routing_entry->destination), dest, sizeof (struct GNUNET_PeerIdentity));
99 memcpy (&(new_routing_entry->prev_hop), prev_hop, sizeof (struct GNUNET_PeerIdentity));
96 100
97 GNUNET_assert (GNUNET_OK == 101 GNUNET_assert (GNUNET_OK ==
98 GNUNET_CONTAINER_multipeermap_put (routing_table, 102 GNUNET_CONTAINER_multipeermap_put (routing_table,
99 dest, new_routing_entry, 103 dest, new_routing_entry,
100 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 104 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
105 return GNUNET_YES;
101} 106}
102 107
103 108
104/**FIXME: Test if its correct or not. 109/**
105 * Find the next hop to send packet to . 110 * Iterate over multiple entries for same destinational value and get
106 * @return next hop peer id 111 * the correct next hop.
112 * @param cls struct RoutingTrail
113 * @param key Destination identity
114 * @param value struct RoutingTrail
115 * @return #GNUNET_YES to continue looking, #GNUNET_NO if we found the next hop
116 */
117int
118get_next_hop (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
119{
120 /* Here you should match if source, prev hop matches if yes then send
121 GNUNET_NO as you don't need to check more entries. */
122 struct RoutingTrail *request = cls;
123 struct RoutingTrail *existing_entry = (struct RoutingTrail *)value;
124
125 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(request->source), &(existing_entry->source)))
126 {
127 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(request->prev_hop), &(existing_entry->prev_hop)))
128 {
129 memcpy (&(request->next_hop), &(existing_entry->next_hop), sizeof (struct GNUNET_PeerIdentity));
130 return GNUNET_YES;
131 }
132 }
133 return GNUNET_NO;
134}
135
136
137/**
138 * Find the next hop to send packet to.
139 * @param source_peer Source of the trail.
140 * @param destination_peer Destination of the trail.
141 * @param prev_hop Previous hop in the trail.
142 * @return Next hop in the trail from source to destination.
107 */ 143 */
108struct GNUNET_PeerIdentity * 144struct GNUNET_PeerIdentity *
109GDS_ROUTING_search(struct GNUNET_PeerIdentity *source_peer, 145GDS_ROUTING_search(struct GNUNET_PeerIdentity *source_peer,
110 struct GNUNET_PeerIdentity *destination_peer) 146 struct GNUNET_PeerIdentity *destination_peer,
147 const struct GNUNET_PeerIdentity *prev_hop)
111{ 148{
112 struct RoutingTrail *trail; 149 struct RoutingTrail *trail;
113 trail = (struct RoutingTrail *)(GNUNET_CONTAINER_multipeermap_get(routing_table,destination_peer)); 150 trail = GNUNET_malloc (sizeof (struct RoutingTrail));
114 151 memcpy (&(trail->destination), destination_peer, sizeof (struct GNUNET_PeerIdentity));
115 if(trail == NULL) 152 memcpy (&(trail->source), source_peer, sizeof (struct GNUNET_PeerIdentity));
116 return NULL; 153 memcpy (&(trail->prev_hop), prev_hop, sizeof (struct GNUNET_PeerIdentity));
117 154 //trail->next_hop = NULL;
118 return &(trail->next_hop); 155 //FPRINTF (stderr,_("\nSUPU ROUTING SEARCH %s, %s, %d"),__FILE__, __func__,__LINE__);
156 GNUNET_CONTAINER_multipeermap_get_multiple (routing_table, destination_peer,
157 get_next_hop, trail);
158 if(trail != NULL)
159 return &(trail->next_hop);
160 else
161 return NULL;
119} 162}
120 163
121 164
diff --git a/src/dht/gnunet-service-xdht_routing.h b/src/dht/gnunet-service-xdht_routing.h
index 44cb07389..92ca5f4f4 100644
--- a/src/dht/gnunet-service-xdht_routing.h
+++ b/src/dht/gnunet-service-xdht_routing.h
@@ -34,10 +34,11 @@
34/** 34/**
35 * Add a new entry to our routing table. 35 * Add a new entry to our routing table.
36*/ 36*/
37void 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 struct GNUNET_PeerIdentity *next_hop,
41 const struct GNUNET_PeerIdentity *prev_hop);
41 42
42 43
43/** 44/**
@@ -46,7 +47,8 @@ GDS_ROUTING_add (struct GNUNET_PeerIdentity *source,
46 */ 47 */
47struct GNUNET_PeerIdentity * 48struct GNUNET_PeerIdentity *
48GDS_ROUTING_search(struct GNUNET_PeerIdentity *source_peer, 49GDS_ROUTING_search(struct GNUNET_PeerIdentity *source_peer,
49 struct GNUNET_PeerIdentity *destination_peer); 50 struct GNUNET_PeerIdentity *destination_peer,
51 const struct GNUNET_PeerIdentity *prev_hop);
50 52
51/** 53/**
52 * Handle a reply (route to origin). Only forwards the reply back to 54 * Handle a reply (route to origin). Only forwards the reply back to