diff options
author | Supriti Singh <supritisingh08@gmail.com> | 2014-05-12 11:05:40 +0000 |
---|---|---|
committer | Supriti Singh <supritisingh08@gmail.com> | 2014-05-12 11:05:40 +0000 |
commit | 3927fc12b66a15a8ce60e3feb0ba33d824848732 (patch) | |
tree | c4d3455493aa897e9117b89e46b81f53d7983df2 /src/dht | |
parent | d9cc0e96edf3637d292bf09671b216bf396faa36 (diff) | |
download | gnunet-3927fc12b66a15a8ce60e3feb0ba33d824848732.tar.gz gnunet-3927fc12b66a15a8ce60e3feb0ba33d824848732.zip |
refactoring the code for finger_table_add(), compare_and_update_predecessor()
Diffstat (limited to 'src/dht')
-rw-r--r-- | src/dht/gnunet-service-xdht.c | 8 | ||||
-rw-r--r-- | src/dht/gnunet-service-xdht_neighbours.c | 1576 | ||||
-rw-r--r-- | src/dht/gnunet-service-xdht_routing.c | 7 | ||||
-rw-r--r-- | src/dht/gnunet-service-xdht_routing.h | 2 |
4 files changed, 923 insertions, 670 deletions
diff --git a/src/dht/gnunet-service-xdht.c b/src/dht/gnunet-service-xdht.c index f76d62078..432fea354 100644 --- a/src/dht/gnunet-service-xdht.c +++ b/src/dht/gnunet-service-xdht.c | |||
@@ -192,14 +192,6 @@ main (int argc, char *const *argv) | |||
192 | { | 192 | { |
193 | int ret; | 193 | int ret; |
194 | 194 | ||
195 | /* FIXME: | ||
196 | Here add a new field threshold to set user defined threshold | ||
197 | on routing table size and trail length. Pass the thr1 and thr2 | ||
198 | to neighbours_init and in neighbours file, in function where we | ||
199 | are adding a new entry into our routing table and trail length, | ||
200 | check the threshold values. After conducting experiments, try to | ||
201 | find the correct threshold to have a balance between attack tolerance | ||
202 | and performance.*/ | ||
203 | ret = | 195 | ret = |
204 | (GNUNET_OK == | 196 | (GNUNET_OK == |
205 | GNUNET_SERVICE_run (argc, argv, "dht", GNUNET_SERVICE_OPTION_NONE, &run, | 197 | GNUNET_SERVICE_run (argc, argv, "dht", GNUNET_SERVICE_OPTION_NONE, &run, |
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c index dc48b3d26..309e1287c 100644 --- a/src/dht/gnunet-service-xdht_neighbours.c +++ b/src/dht/gnunet-service-xdht_neighbours.c | |||
@@ -45,27 +45,22 @@ | |||
45 | #include "dht.h" | 45 | #include "dht.h" |
46 | 46 | ||
47 | /* TODO: | 47 | /* TODO: |
48 | 1. Use a global array of all known peers in find_successor, Only when | 48 | 1. to randomly choose one of the routes in case there are multiple |
49 | a new peer is added in finger or friend peer map, then re calculate | 49 | routes to reach to the finger. |
50 | the array. Or else use the old one. The benefit of having this list is something | 50 | 2. Use a global array of all known peers in find_successor, Only when |
51 | * I am not sure. only when the code is complete and working I will do this part. | 51 | a new peer is added in finger or friend peer map, then re calculate |
52 | 2. Structure alignment. | 52 | the array. Or else use the old one. The benefit of having this list is something |
53 | 3. In case of trail setup, you can see the comment on top of finger map index, | 53 | I am not sure. only when the code is complete and working I will do this part. |
54 | * trial length --> in NBO. Check how do we keep it in NBO, and make sure its | 54 | 3. Structure alignment. |
55 | * same everywhere. When i send any message across the network i use htonl, so that | 55 | 4. Check where do you set all_friends_trail_threshold? In select_random_friend? |
56 | * converts it into network byte order. | 56 | 5. In put, we don't have anything like put result. so we are not adding anything |
57 | 4.THAT IN ROUTING TABLE SOURCE PEER IS INDEED THE SOURCE PEER. | 57 | in the routing table. |
58 | should trail contain last element as finger or just the last element.? if | 58 | */ |
59 | you can get some value then you should not keep at different places. | ||
60 | remove finger as last element in the trail. | ||
61 | 5. I have removed the last element in the trail which was finger identity as we | ||
62 | * are already sending finger identity in the message. handle the case in case | ||
63 | * of notify new successor and verify the successor. */ | ||
64 | 59 | ||
65 | /** | 60 | /** |
66 | * Maximum possible fingers of a peer. | 61 | * Maximum possible fingers of a peer. |
67 | */ | 62 | */ |
68 | #define MAX_FINGERS 65 | 63 | #define MAX_FINGERS 66 |
69 | 64 | ||
70 | /** | 65 | /** |
71 | * Maximum allowed number of pending messages per friend peer. | 66 | * Maximum allowed number of pending messages per friend peer. |
@@ -796,35 +791,119 @@ search_my_index (const struct GNUNET_PeerIdentity *trail, | |||
796 | return GNUNET_SYSERR; | 791 | return GNUNET_SYSERR; |
797 | } | 792 | } |
798 | 793 | ||
794 | /** | ||
795 | * Compare two peer identities. | ||
796 | * @param p1 Peer identity | ||
797 | * @param p2 Peer identity | ||
798 | * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2. | ||
799 | */ | ||
800 | static int | ||
801 | compare_peer_id (const void *p1, const void *p2) | ||
802 | { | ||
803 | struct Sorting_List *p11; | ||
804 | struct Sorting_List *p22; | ||
805 | int ret; | ||
806 | p11 = GNUNET_malloc (sizeof (struct Sorting_List)); | ||
807 | p22 = GNUNET_malloc (sizeof (struct Sorting_List)); | ||
808 | p11 = (struct Sorting_List *)p1; | ||
809 | p22 = (struct Sorting_List *)p2; | ||
810 | ret = ( (p11->peer_id) > (p22->peer_id) ) ? 1 : | ||
811 | ( (p11->peer_id) == (p22->peer_id) ) ? 0 : -1; | ||
812 | return ret; | ||
813 | } | ||
814 | |||
799 | 815 | ||
800 | /** | 816 | /** |
801 | * Invert the trail list. | 817 | * Return the predecessor of value in all_known_peers. |
802 | * @param existing_trail Trail | 818 | * @param all_known_peers list of all the peers |
803 | * @param trail_length Number of peers in the existing trail. | 819 | * @param value value we have to search in the all_known_peers. |
804 | * @return | 820 | * @param size Total numbers of elements |
821 | * @return Predecessor | ||
805 | */ | 822 | */ |
806 | static struct GNUNET_PeerIdentity * | 823 | static struct Sorting_List * |
807 | invert_trail_list (struct GNUNET_PeerIdentity *existing_trail, | 824 | find_closest_predecessor(struct Sorting_List *all_known_peers, uint64_t value, |
808 | unsigned int trail_length) | 825 | unsigned int size) |
809 | { | 826 | { |
810 | int i; | 827 | int first; |
811 | int j; | 828 | int last; |
812 | struct GNUNET_PeerIdentity *new_trail; | 829 | int middle; |
813 | 830 | ||
814 | j = 0; | 831 | first = 0; |
815 | new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length); | 832 | last = size - 1; |
833 | middle = (first + last)/2; | ||
816 | 834 | ||
817 | if (trail_length > 1) | 835 | while(first <= last) |
818 | { | 836 | { |
819 | i = trail_length - 2; | 837 | if(all_known_peers[middle].peer_id < value) |
820 | while (i >= 0 ) | ||
821 | { | 838 | { |
822 | memcpy( &new_trail[j], &existing_trail[i], sizeof (struct GNUNET_PeerIdentity)); | 839 | first = middle + 1; |
823 | i--; | 840 | } |
824 | j++; | 841 | else if(all_known_peers[middle].peer_id == value) |
842 | { | ||
843 | if(middle == (0)) | ||
844 | { | ||
845 | return &all_known_peers[size - 1]; | ||
846 | } | ||
847 | else | ||
848 | { | ||
849 | return &all_known_peers[middle - 1]; | ||
850 | } | ||
825 | } | 851 | } |
852 | else | ||
853 | { | ||
854 | last = middle - 1; | ||
855 | } | ||
856 | |||
857 | middle = (first + last)/2; | ||
826 | } | 858 | } |
827 | return new_trail; | 859 | return NULL; |
860 | } | ||
861 | |||
862 | |||
863 | /** | ||
864 | * Return the successor of value in all_known_peers. | ||
865 | * @param all_known_peers list of all the peers | ||
866 | * @param value value we have to search in the all_known_peers. | ||
867 | * @param size Total numbers of elements | ||
868 | * @return Successor | ||
869 | */ | ||
870 | static struct Sorting_List * | ||
871 | find_closest_successor(struct Sorting_List *all_known_peers, uint64_t value, | ||
872 | unsigned int size) | ||
873 | { | ||
874 | int first; | ||
875 | int last; | ||
876 | int middle; | ||
877 | |||
878 | first = 0; | ||
879 | last = size - 1; | ||
880 | middle = (first + last)/2; | ||
881 | |||
882 | while(first <= last) | ||
883 | { | ||
884 | if(all_known_peers[middle].peer_id < value) | ||
885 | { | ||
886 | first = middle + 1; | ||
887 | } | ||
888 | else if(all_known_peers[middle].peer_id == value) | ||
889 | { | ||
890 | if(middle == (size -1)) | ||
891 | { | ||
892 | return &all_known_peers[0]; | ||
893 | } | ||
894 | else | ||
895 | { | ||
896 | return &all_known_peers[middle+1]; | ||
897 | } | ||
898 | } | ||
899 | else | ||
900 | { | ||
901 | last = middle - 1; | ||
902 | } | ||
903 | |||
904 | middle = (first + last)/2; | ||
905 | } | ||
906 | return NULL; | ||
828 | } | 907 | } |
829 | 908 | ||
830 | 909 | ||
@@ -989,7 +1068,7 @@ GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity *source_peer, | |||
989 | tsm->trail_length = htonl (trail_length); | 1068 | tsm->trail_length = htonl (trail_length); |
990 | tsm->finger_map_index = htonl (finger_map_index); | 1069 | tsm->finger_map_index = htonl (finger_map_index); |
991 | 1070 | ||
992 | if (trail_peer_list != NULL) | 1071 | if (trail_length > 0) |
993 | { | 1072 | { |
994 | peer_list = (struct GNUNET_PeerIdentity *) &tsm[1]; | 1073 | peer_list = (struct GNUNET_PeerIdentity *) &tsm[1]; |
995 | memcpy (peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity)); | 1074 | memcpy (peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity)); |
@@ -1053,8 +1132,9 @@ GDS_NEIGHBOURS_send_trail_setup_result (const struct GNUNET_PeerIdentity *destin | |||
1053 | 1132 | ||
1054 | peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1]; | 1133 | peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1]; |
1055 | if (trail_length > 0) | 1134 | if (trail_length > 0) |
1135 | { | ||
1056 | memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | 1136 | memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); |
1057 | 1137 | } | |
1058 | /* Send the message to chosen friend. */ | 1138 | /* Send the message to chosen friend. */ |
1059 | GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); | 1139 | GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); |
1060 | target_friend->pending_count++; | 1140 | target_friend->pending_count++; |
@@ -1106,8 +1186,12 @@ void GDS_NEIGHBOURS_send_verify_successor(const struct GNUNET_PeerIdentity *sour | |||
1106 | memcpy (&(vsm->successor), successor, sizeof (struct GNUNET_PeerIdentity)); | 1186 | memcpy (&(vsm->successor), successor, sizeof (struct GNUNET_PeerIdentity)); |
1107 | memcpy (&(vsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); | 1187 | memcpy (&(vsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); |
1108 | vsm->trail_length = htonl (trail_length); | 1188 | vsm->trail_length = htonl (trail_length); |
1109 | peer_list = (struct GNUNET_PeerIdentity *) &vsm[1]; | 1189 | |
1110 | memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | 1190 | if (trail_length > 0) |
1191 | { | ||
1192 | peer_list = (struct GNUNET_PeerIdentity *) &vsm[1]; | ||
1193 | memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | ||
1194 | } | ||
1111 | 1195 | ||
1112 | /* Send the message to chosen friend. */ | 1196 | /* Send the message to chosen friend. */ |
1113 | GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); | 1197 | GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); |
@@ -1165,8 +1249,11 @@ void GDS_NEIGHBOURS_send_verify_successor_result (const struct GNUNET_PeerIdenti | |||
1165 | memcpy (&(vsmr->source_successor), source_successor, sizeof (struct GNUNET_PeerIdentity)); | 1249 | memcpy (&(vsmr->source_successor), source_successor, sizeof (struct GNUNET_PeerIdentity)); |
1166 | memcpy (&(vsmr->my_predecessor), my_predecessor, sizeof (struct GNUNET_PeerIdentity)); | 1250 | memcpy (&(vsmr->my_predecessor), my_predecessor, sizeof (struct GNUNET_PeerIdentity)); |
1167 | vsmr->trail_length = htonl (trail_length); | 1251 | vsmr->trail_length = htonl (trail_length); |
1168 | peer_list = (struct GNUNET_PeerIdentity *) &vsmr[1]; | 1252 | if (trail_length > 0) |
1169 | memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | 1253 | { |
1254 | peer_list = (struct GNUNET_PeerIdentity *) &vsmr[1]; | ||
1255 | memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | ||
1256 | } | ||
1170 | 1257 | ||
1171 | /* Send the message to chosen friend. */ | 1258 | /* Send the message to chosen friend. */ |
1172 | GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); | 1259 | GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); |
@@ -1220,7 +1307,8 @@ GDS_NEIGHBOURS_send_notify_new_successor (const struct GNUNET_PeerIdentity *sour | |||
1220 | memcpy (&(nsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); | 1307 | memcpy (&(nsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity)); |
1221 | memcpy (&(nsm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity)); | 1308 | memcpy (&(nsm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity)); |
1222 | nsm->trail_length = htonl (trail_length); | 1309 | nsm->trail_length = htonl (trail_length); |
1223 | 1310 | /* FIXME: Here I am not checking the trail length, as I am assuming that for new | |
1311 | successor our old successor is a part of trail, so trail length > 1. */ | ||
1224 | peer_list = (struct GNUNET_PeerIdentity *) &nsm[1]; | 1312 | peer_list = (struct GNUNET_PeerIdentity *) &nsm[1]; |
1225 | memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | 1313 | memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); |
1226 | 1314 | ||
@@ -1287,13 +1375,15 @@ GDS_NEIGHBOURS_send_trail_teardown (struct GNUNET_PeerIdentity *source_peer, | |||
1287 | 1375 | ||
1288 | 1376 | ||
1289 | /** | 1377 | /** |
1378 | * FIMXE: Change the return value, to handle the case where all friends | ||
1379 | * are congested. | ||
1290 | * FIXME: Handle congested peer - don't choose this friend, also don't choose | 1380 | * FIXME: Handle congested peer - don't choose this friend, also don't choose |
1291 | * the friend if the link threshold has crossed. Not implemented yet. | 1381 | * the friend if the link threshold has crossed. Not implemented yet. |
1292 | * Randomly choose one of your friends from the friends_peer map | 1382 | * Randomly choose one of your friends from the friends_peer map |
1293 | * @return Friend | 1383 | * @return Friend |
1294 | */ | 1384 | */ |
1295 | static struct FriendInfo * | 1385 | static struct FriendInfo * |
1296 | select_random_friend (struct GNUNET_PeerIdentity *congested_peer) | 1386 | select_random_friend () |
1297 | { | 1387 | { |
1298 | unsigned int current_size; | 1388 | unsigned int current_size; |
1299 | unsigned int *index; | 1389 | unsigned int *index; |
@@ -1380,11 +1470,10 @@ send_verify_successor_message (void *cls, | |||
1380 | struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; | 1470 | struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; |
1381 | struct GNUNET_PeerIdentity key_ret; | 1471 | struct GNUNET_PeerIdentity key_ret; |
1382 | struct FriendInfo *target_friend; | 1472 | struct FriendInfo *target_friend; |
1383 | struct GNUNET_PeerIdentity *next_hop; | 1473 | struct GNUNET_PeerIdentity next_hop; |
1384 | struct GNUNET_PeerIdentity *peer_list; | 1474 | struct GNUNET_PeerIdentity *peer_list; |
1385 | struct FingerInfo *finger; | 1475 | struct FingerInfo *finger; |
1386 | unsigned int finger_index; | 1476 | unsigned int finger_index; |
1387 | unsigned int i; | ||
1388 | int flag = 0; | 1477 | int flag = 0; |
1389 | 1478 | ||
1390 | /* Find the successor from the finger peermap.*/ | 1479 | /* Find the successor from the finger peermap.*/ |
@@ -1404,32 +1493,41 @@ send_verify_successor_message (void *cls, | |||
1404 | GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); | 1493 | GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); |
1405 | 1494 | ||
1406 | if( flag == 0) | 1495 | if( flag == 0) |
1407 | goto send_new_request; | ||
1408 | |||
1409 | peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->first_trail_length); | ||
1410 | |||
1411 | struct TrailPeerList *iterate; | ||
1412 | iterate = finger->first_trail_head; | ||
1413 | i = 0; | ||
1414 | while ( i < (finger->first_trail_length)) | ||
1415 | { | 1496 | { |
1416 | memcpy (&peer_list[i], &(iterate->peer), sizeof (struct GNUNET_PeerIdentity)); | 1497 | goto send_new_request; |
1417 | iterate = iterate->next; | ||
1418 | i++; | ||
1419 | } | 1498 | } |
1420 | |||
1421 | next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); | ||
1422 | memcpy (next_hop, &peer_list[0], sizeof (struct GNUNET_PeerIdentity)); | ||
1423 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); | ||
1424 | 1499 | ||
1500 | if (finger->first_trail_length > 0) | ||
1501 | { | ||
1502 | struct TrailPeerList *iterate; | ||
1503 | int i = 0; | ||
1504 | peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->first_trail_length); | ||
1505 | iterate = finger->first_trail_head; | ||
1506 | |||
1507 | while ( i < (finger->first_trail_length)) | ||
1508 | { | ||
1509 | |||
1510 | memcpy (&peer_list[i], &(iterate->peer), sizeof (struct GNUNET_PeerIdentity)); | ||
1511 | iterate = iterate->next; | ||
1512 | i++; | ||
1513 | } | ||
1514 | memcpy (&next_hop, &peer_list[0], sizeof (struct GNUNET_PeerIdentity)); | ||
1515 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); | ||
1516 | } | ||
1517 | else | ||
1518 | { | ||
1519 | /* If trail length = 0, then our successor is our friend. */ | ||
1520 | peer_list = NULL; | ||
1521 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
1522 | &(finger->finger_identity)); | ||
1523 | } | ||
1524 | |||
1425 | GDS_NEIGHBOURS_send_verify_successor (&my_identity, | 1525 | GDS_NEIGHBOURS_send_verify_successor (&my_identity, |
1426 | &(finger->finger_identity), | 1526 | &(finger->finger_identity), |
1427 | target_friend, | 1527 | target_friend, |
1428 | peer_list, | 1528 | peer_list, |
1429 | finger->first_trail_length); | 1529 | finger->first_trail_length); |
1430 | 1530 | ||
1431 | |||
1432 | /* FIXME: Understand what this function is actually doing here. */ | ||
1433 | send_new_request: | 1531 | send_new_request: |
1434 | next_send_time.rel_value_us = | 1532 | next_send_time.rel_value_us = |
1435 | DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us + | 1533 | DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us + |
@@ -1443,6 +1541,11 @@ send_verify_successor_message (void *cls, | |||
1443 | 1541 | ||
1444 | 1542 | ||
1445 | /** | 1543 | /** |
1544 | * FIXME: | ||
1545 | * 1. Need to handle the case where all friends are either congested or | ||
1546 | * have reached their threshold. | ||
1547 | * 2. If we need all_friends_trail_threshold | ||
1548 | * 3. do we need to check if friend peermap is empty or not. | ||
1446 | * Choose a random friend and start looking for the trail to reach to | 1549 | * Choose a random friend and start looking for the trail to reach to |
1447 | * finger identity through this random friend. | 1550 | * finger identity through this random friend. |
1448 | * | 1551 | * |
@@ -1462,39 +1565,20 @@ send_find_finger_trail_message (void *cls, | |||
1462 | DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us + | 1565 | DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us + |
1463 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | 1566 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, |
1464 | DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us); | 1567 | DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us); |
1465 | |||
1466 | /* FIXME; if all the friend have reached their threshold, then don't schedule | ||
1467 | * the task till the all_friends_trail_threshold gets reset. It will be | ||
1468 | * scheduled from there. So, in finger table when we remove an entry and the new | ||
1469 | * entry does not have the same friend as the first hop, then decrement the | ||
1470 | * threshold limit. and schedule this task. | ||
1471 | IMPORTANT: reset the value some where. Better name */ | ||
1472 | if (GNUNET_YES == all_friends_trail_threshold) | ||
1473 | { | ||
1474 | return; | ||
1475 | } | ||
1476 | |||
1477 | find_finger_trail_task = | 1568 | find_finger_trail_task = |
1478 | GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message, | 1569 | GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message, |
1479 | NULL); | 1570 | NULL); |
1480 | 1571 | ||
1481 | /* Friend peermap is empty but this task has already been started it failed.*/ | 1572 | if (GNUNET_YES == all_friends_trail_threshold) |
1482 | if (GNUNET_CONTAINER_multipeermap_size (friend_peermap) == 0) | ||
1483 | { | 1573 | { |
1484 | GNUNET_break(0); | 1574 | /* All friends in friend peer map, have reached their trail threshold. No |
1575 | more new trail can be created. */ | ||
1485 | return; | 1576 | return; |
1486 | } | 1577 | } |
1487 | 1578 | ||
1488 | target_friend = select_random_friend (NULL); | 1579 | target_friend = select_random_friend (); |
1489 | |||
1490 | if (NULL == target_friend) | 1580 | if (NULL == target_friend) |
1491 | { | 1581 | { |
1492 | /* FIXME URGENT: Here we can get NULL all of the friends have reached their threshold. | ||
1493 | * At the moment, the code for select_random_friend, is not handling it. In such a | ||
1494 | * case I think we can set a flag, and only when any value for any friend gets | ||
1495 | * decremented,(which can happen only in finger table, when we remove an entry | ||
1496 | * from our finger table, and we are not part of the trail to reach to that | ||
1497 | * finger any more, t then reset the flag and schedule the code from there. */ | ||
1498 | all_friends_trail_threshold = GNUNET_YES; | 1582 | all_friends_trail_threshold = GNUNET_YES; |
1499 | return; | 1583 | return; |
1500 | } | 1584 | } |
@@ -1509,251 +1593,210 @@ send_find_finger_trail_message (void *cls, | |||
1509 | } | 1593 | } |
1510 | 1594 | ||
1511 | finger_map_index = current_search_finger_index; | 1595 | finger_map_index = current_search_finger_index; |
1512 | |||
1513 | /* URGENT :FIXME: In case the packet is not sent to a finger, then current_source is the | ||
1514 | * peer which sent the packet and current_destination which recevied it. Now | ||
1515 | * these fields are not always used. Think of some way to remove these variables. */ | ||
1516 | GDS_NEIGHBOURS_send_trail_setup (&my_identity, finger_identity, &(target_friend->id), | 1596 | GDS_NEIGHBOURS_send_trail_setup (&my_identity, finger_identity, &(target_friend->id), |
1517 | &my_identity, target_friend, 0, NULL, finger_map_index); | 1597 | &my_identity, target_friend, 0, NULL, finger_map_index); |
1518 | } | 1598 | } |
1519 | 1599 | ||
1520 | 1600 | ||
1601 | |||
1602 | |||
1603 | /* In this function, we want to return the compressed trail and the trail length. | ||
1604 | We can send back a new trail and update the trail length value as we get as | ||
1605 | parameter to our function. There are many cases where we don't need to call | ||
1606 | this function. Move that logic to calling function. */ | ||
1521 | /** | 1607 | /** |
1522 | * FIXME: How do I send back the updated trail. | 1608 | * Scan the trail to check if any of my own friend is part of trail. If yes |
1523 | * Scan the trail to check if any on my own friend is part of trail. If yes | 1609 | * then shortcut the trail, update trail length and send back the new trail. |
1524 | * the shortcut the trail and update the finger_trail and trail_length. | 1610 | * @param trail[Out] Current trail to reach to @a finger, will be updated |
1525 | * @param finger_trail | 1611 | * in case we compress the trail. |
1526 | * @param trail_length | 1612 | * @param trail_length[Out] Number of peers in @a finger_trail, will be updated |
1527 | * @return | 1613 | * in case we compress the trail. |
1614 | * @param finger Finger identity | ||
1528 | */ | 1615 | */ |
1529 | static struct GNUNET_PeerIdentity * | 1616 | static void |
1530 | scan_and_compress_trail (struct GNUNET_PeerIdentity *finger_trail, unsigned int trail_length, | 1617 | scan_and_compress_trail (struct GNUNET_PeerIdentity *trail, |
1531 | const struct GNUNET_PeerIdentity *finger) | 1618 | unsigned int *trail_length, |
1619 | const struct GNUNET_PeerIdentity *finger) | ||
1532 | { | 1620 | { |
1533 | /* start from the second element as first element will always be your friend. | 1621 | int i; |
1534 | In case trail_length = 2, and the last element is also your friend then you | 1622 | |
1535 | should delete the first element. In other cases go through the list and check | 1623 | /* If finger is my friend, then set trail_length = 0;*/ |
1536 | if the trail */ | 1624 | if (GNUNET_CONTAINER_multipeermap_get (friend_peermap, finger)) |
1537 | int i = trail_length - 1; | 1625 | { |
1626 | /* supu' delete entry from the thrail. */ | ||
1627 | trail_length = 0; | ||
1628 | trail = NULL; | ||
1629 | return; | ||
1630 | } | ||
1538 | 1631 | ||
1632 | i = *trail_length - 1; | ||
1539 | while (i > 1) | 1633 | while (i > 1) |
1540 | { | 1634 | { |
1541 | if (NULL == GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_trail[i])) | 1635 | if (NULL == GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[i])) |
1542 | { | 1636 | { |
1543 | /* This element of trail is not my friend. */ | 1637 | /* This element of trail is not my friend. */ |
1544 | i--; | 1638 | i--; |
1545 | } | 1639 | } |
1546 | else | 1640 | else |
1547 | { | 1641 | { |
1548 | /* If for any i>1 we found a friend, then we can use this friend as the | 1642 | /* A --> B(friend 1) --> C(friend 2)--> D ---> E, then we can rewrite the trail as |
1549 | first link and forget about all the peers behind it. But we need to first | 1643 | * C --> D --> E, |
1550 | copy the peers behind it. send a trail tear down message along | 1644 | * Now, we should remove the entry from A's routing table, B's routing table |
1551 | that line. */ | 1645 | * and update the entry in C's routing table. Rest everything will be same. |
1646 | * C's routing table should have source peer as the prev.hop. | ||
1647 | * In case we found a friend not at i = 0, then we can discard all the | ||
1648 | peers before it in the trail and short cut the path. We need to send | ||
1649 | trail teardown message also but not to all the peers in the trail. only | ||
1650 | the peer just behind me and also update the routing table of the friend, | ||
1651 | to prev hop as the source peer ie my_identity. */ | ||
1552 | struct GNUNET_PeerIdentity *discarded_trail; | 1652 | struct GNUNET_PeerIdentity *discarded_trail; |
1553 | struct FriendInfo *target_friend; | 1653 | struct FriendInfo *target_friend; |
1554 | /* FIXME: Create a new trail. to send back*/ | 1654 | int discarded_trail_length; |
1555 | int discarded_trail_length = trail_length - i; | ||
1556 | int j = 0; | 1655 | int j = 0; |
1656 | /* Here I am adding the friend (C) found to the discarded trail also, as we | ||
1657 | need to update its routing table also. */ | ||
1658 | discarded_trail_length = i; | ||
1557 | discarded_trail = GNUNET_malloc (discarded_trail_length * sizeof (struct GNUNET_PeerIdentity)); | 1659 | discarded_trail = GNUNET_malloc (discarded_trail_length * sizeof (struct GNUNET_PeerIdentity)); |
1558 | 1660 | memcpy (discarded_trail, trail, discarded_trail_length * sizeof (struct GNUNET_PeerIdentity)); | |
1559 | while (j < (discarded_trail_length + 1)) | 1661 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[0]); |
1662 | /* send_update_routing_table(friend). so that it removes prev hop | ||
1663 | and update it to source for given finger. */ | ||
1664 | /* FIXME: Modify trail_teardown function to handle such cases. In case | ||
1665 | the last element of the trail update the routing table, in case it | ||
1666 | is trail compression. But teardown is called from various places so | ||
1667 | need to differentiate these two cases. URGENT*/ | ||
1668 | GDS_NEIGHBOURS_send_trail_teardown (&my_identity, finger, discarded_trail, | ||
1669 | discarded_trail_length, target_friend); | ||
1670 | |||
1671 | /* Copy the trail from index i to index trail_length -1 and change | ||
1672 | trail length and return */ | ||
1673 | while (i < *trail_length) | ||
1560 | { | 1674 | { |
1561 | memcpy (&discarded_trail[j], &finger_trail[j], sizeof (struct GNUNET_PeerIdentity)); | 1675 | memcpy (&trail[j], &trail[i], sizeof(struct GNUNET_PeerIdentity)); |
1562 | j++; | 1676 | j++; |
1677 | i++; | ||
1563 | } | 1678 | } |
1564 | 1679 | *trail_length = j+1; | |
1565 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_trail[0]); | 1680 | return; |
1566 | /* FIXME: THAT IN ROUTING TABLE SOURCE PEER IS INDEED THE SOURCE PEER. | ||
1567 | * should trail contain last element as finger or just the last element.? if | ||
1568 | * you can get some value then you should not keep at different places. | ||
1569 | * remove finger as last element in the trail. */ | ||
1570 | GDS_NEIGHBOURS_send_trail_teardown (&my_identity, finger, discarded_trail, | ||
1571 | discarded_trail_length, target_friend); | ||
1572 | |||
1573 | /* fixme: CHANGE IT TO NEW TRAIL */ | ||
1574 | return NULL; | ||
1575 | } | 1681 | } |
1576 | } | 1682 | } |
1577 | return NULL; | 1683 | return; |
1578 | } | 1684 | } |
1579 | 1685 | ||
1580 | 1686 | ||
1581 | /** | 1687 | /** |
1582 | * TODO: | 1688 | * FIXME: Is this correct? Here I am using dll_remove and its documentation |
1583 | * To see the logic better, I guess it better that function calling | 1689 | * reads something else. Verify. Urgent. |
1584 | * free_finger, decrement the count of the trail going through them | ||
1585 | * reset all_friends_trail_threshold. In case you are removing an entry from | ||
1586 | * finger table, and the new entry has the first friend different from the old | ||
1587 | * entry, then reset this all_friends_trail_threshold, if it is set to GNUNET_YES. | ||
1588 | * and also schedule send_find_finger_trail_message. | ||
1589 | * Free finger and its trail. | 1690 | * Free finger and its trail. |
1590 | * @param remove_finger Finger to be freed. | 1691 | * @param finger Finger to be freed. |
1591 | */ | 1692 | */ |
1592 | static void | 1693 | static void |
1593 | free_finger (struct FingerInfo *finger) | 1694 | free_finger (struct FingerInfo *finger) |
1594 | { | 1695 | { |
1595 | struct TrailPeerList *peer; | 1696 | struct TrailPeerList *peer; |
1596 | struct FriendInfo *first_trail_friend; | 1697 | |
1597 | struct FriendInfo *second_trail_friend; | 1698 | if(finger->first_trail_head != NULL) |
1598 | |||
1599 | first_trail_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
1600 | &(finger->first_trail_head->peer)); | ||
1601 | second_trail_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
1602 | &(finger->second_trail_head->peer)); | ||
1603 | |||
1604 | first_trail_friend->trails_count--; | ||
1605 | second_trail_friend->trails_count--; | ||
1606 | |||
1607 | /* FIXME: Here we should reset the all_peers_trail_count to GNUNET_NO, and | ||
1608 | send_find_finger_trail_message. */ | ||
1609 | while (NULL != (peer = finger->first_trail_head)) | ||
1610 | { | 1699 | { |
1611 | GNUNET_CONTAINER_DLL_remove (finger->first_trail_head, finger->first_trail_tail, peer); | 1700 | while (NULL != (peer = finger->first_trail_head)) |
1612 | GNUNET_free (peer); | 1701 | { |
1702 | GNUNET_CONTAINER_DLL_remove (finger->first_trail_head, finger->first_trail_tail, peer); | ||
1703 | GNUNET_free (peer); | ||
1704 | } | ||
1613 | } | 1705 | } |
1614 | 1706 | ||
1615 | while (NULL != (peer = finger->second_trail_head)) | 1707 | if (finger->second_trail_head != NULL) |
1616 | { | 1708 | { |
1617 | GNUNET_CONTAINER_DLL_remove (finger->second_trail_head, finger->second_trail_tail, peer); | 1709 | while (NULL != (peer = finger->second_trail_head)) |
1618 | GNUNET_free (peer); | 1710 | { |
1711 | GNUNET_CONTAINER_DLL_remove (finger->second_trail_head, finger->second_trail_tail, peer); | ||
1712 | GNUNET_free (peer); | ||
1713 | } | ||
1714 | GNUNET_free (finger); | ||
1619 | } | 1715 | } |
1620 | GNUNET_free (finger); | ||
1621 | } | 1716 | } |
1622 | 1717 | ||
1623 | 1718 | ||
1624 | /** | 1719 | /** |
1625 | * FIMXE: Change the function, here you need to invert the trail. | 1720 | * * 1.* If you remove an entry from finger table, and if the finger is not your friend |
1721 | * and the trail length > 1 for the finger that you removed, then you should send | ||
1722 | * a trail_teardown message along the trail. so that the peers which have an | ||
1723 | * entry in their routing table for this trail can remove it from their routing | ||
1724 | * table. | ||
1725 | * Better name | ||
1726 | * TODO: First check if both the trails are present if yes then send it | ||
1727 | * for both of them. | ||
1626 | * @param existing_finger | 1728 | * @param existing_finger |
1627 | * @param new_finger | ||
1628 | * @param trail | ||
1629 | * @param trail_length | ||
1630 | * @return | ||
1631 | */ | 1729 | */ |
1632 | static | 1730 | static |
1633 | int select_correct_predecessor (struct FingerInfo *existing_finger, | 1731 | void send_trail_teardown (struct FingerInfo *existing_finger) |
1634 | const struct GNUNET_PeerIdentity *new_finger, | ||
1635 | struct GNUNET_PeerIdentity *trail, | ||
1636 | unsigned int trail_length) | ||
1637 | { | 1732 | { |
1638 | int val = GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), new_finger); | 1733 | struct GNUNET_PeerIdentity *peer_list; |
1639 | if (0 == val) | 1734 | struct FriendInfo *friend; |
1640 | { | 1735 | struct TrailPeerList *finger_trail; |
1641 | /* FIXME: if the new entry = old entry, then compare the trails, and see if the trails | 1736 | int existing_finger_trail_length = existing_finger->first_trail_length; |
1642 | are disjoint, then send GNUNET_YES, but don't free old finger. But first you | 1737 | int i = 0; |
1643 | * should collapse the trail and then do comparison. Also, if you are collapsing | 1738 | |
1644 | * for one case then you should do it for all the cases where you are sending | 1739 | |
1645 | * GNUNET_YES. */ | 1740 | if (existing_finger->first_trail_length == 0) |
1646 | /* Scan the trail for a friend and shorten if possible. */ | 1741 | return; |
1647 | scan_and_compress_trail (trail, trail_length, new_finger); | 1742 | finger_trail = existing_finger->first_trail_head; |
1648 | return GNUNET_YES; | 1743 | friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(finger_trail->peer)); |
1649 | } | 1744 | peer_list = GNUNET_malloc ( existing_finger_trail_length * sizeof (struct GNUNET_PeerIdentity)); |
1650 | else if (val < 0) | 1745 | while (i < existing_finger->first_trail_length) |
1651 | { | 1746 | { |
1652 | /* If the new entry is closest one, then free the old entry, send a trail_teardown message.*/ | 1747 | memcpy (&peer_list[i], &(finger_trail->peer), sizeof (struct GNUNET_PeerIdentity)); |
1653 | struct GNUNET_PeerIdentity *peer_list; | 1748 | finger_trail = finger_trail->next; |
1654 | struct FriendInfo *friend; | 1749 | i++; |
1655 | struct TrailPeerList *finger_trail; | 1750 | } |
1656 | int existing_finger_trail_length = existing_finger->first_trail_length; | ||
1657 | int i = 0; | ||
1658 | |||
1659 | finger_trail = existing_finger->first_trail_head; | ||
1660 | friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(finger_trail->peer)); | ||
1661 | peer_list = GNUNET_malloc ( existing_finger_trail_length * sizeof (struct GNUNET_PeerIdentity)); | ||
1662 | while (i < existing_finger->first_trail_length) | ||
1663 | { | ||
1664 | memcpy (&peer_list[i], &(finger_trail->peer), sizeof (struct GNUNET_PeerIdentity)); | ||
1665 | finger_trail = finger_trail->next; | ||
1666 | i++; | ||
1667 | } | ||
1668 | |||
1669 | GDS_NEIGHBOURS_send_trail_teardown (&my_identity, &(existing_finger->finger_identity), | ||
1670 | peer_list, existing_finger_trail_length, friend); | ||
1671 | 1751 | ||
1672 | free_finger (existing_finger); | 1752 | GDS_NEIGHBOURS_send_trail_teardown (&my_identity, &(existing_finger->finger_identity), |
1673 | scan_and_compress_trail (trail, trail_length, new_finger); | 1753 | peer_list, existing_finger_trail_length, friend); |
1674 | return GNUNET_YES; | ||
1675 | } | ||
1676 | else | ||
1677 | { | ||
1678 | /* If the old entry is closest then just return GNUNET_NO.*/ | ||
1679 | return GNUNET_NO; | ||
1680 | } | ||
1681 | return GNUNET_SYSERR; | ||
1682 | } | 1754 | } |
1683 | 1755 | ||
1684 | 1756 | ||
1685 | /** | 1757 | /** |
1686 | * Check if there is a predecessor in our finger peer map or not. | 1758 | * Add a new trail to reach an existing finger in finger peermap. |
1687 | * If no, then return GNUNET_YES | 1759 | * @param existing_finger |
1688 | * else compare existing predecessor and peer, and find the correct | 1760 | * @param trail |
1689 | * predecessor. | 1761 | * @param trail_length |
1690 | * @param existing_predecessor | ||
1691 | * @param new_predecessor | ||
1692 | * @return #GNUNET_YES if new peer is predecessor | ||
1693 | * #GNUNET_NO if new peer is not the predecessor. | ||
1694 | */ | 1762 | */ |
1695 | static void | 1763 | static |
1696 | compare_and_update_predecessor (struct GNUNET_PeerIdentity *peer, | 1764 | void add_new_trail (struct FingerInfo *existing_finger, |
1697 | struct GNUNET_PeerIdentity *trail, | 1765 | struct GNUNET_PeerIdentity *trail, |
1698 | unsigned int trail_length) | 1766 | unsigned int trail_length) |
1699 | { | 1767 | { |
1700 | /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */ | ||
1701 | struct FingerInfo *existing_finger; | ||
1702 | struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; | ||
1703 | struct FingerInfo *new_finger_entry; | ||
1704 | int i; | 1768 | int i; |
1705 | int predecessor_flag = 0; | 1769 | i = 0; |
1706 | 1770 | ||
1707 | finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); | 1771 | if (existing_finger->second_trail_head != NULL) |
1708 | for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++) | ||
1709 | { | 1772 | { |
1710 | if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, NULL, | 1773 | while (i < trail_length) |
1711 | (const void **)&existing_finger)) | ||
1712 | { | 1774 | { |
1713 | if (existing_finger->finger_map_index == PREDECESSOR_FINGER_ID) | 1775 | struct TrailPeerList *element; |
1714 | { | 1776 | element = GNUNET_malloc (sizeof (struct TrailPeerList)); |
1715 | predecessor_flag = 1; | 1777 | element->next = NULL; |
1716 | break; | 1778 | element->prev = NULL; |
1717 | } | 1779 | |
1780 | memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity)); | ||
1781 | GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element); | ||
1782 | i++; | ||
1718 | } | 1783 | } |
1719 | } | 1784 | } |
1720 | 1785 | else if (existing_finger->second_trail_head != NULL) | |
1721 | if (predecessor_flag != 0) | ||
1722 | { | ||
1723 | /* There is a predecessor entry. Now we need to find out which one is | ||
1724 | * the closest one. If both are same then how to handle. */ | ||
1725 | if(select_correct_predecessor (existing_finger, peer, trail, trail_length) == GNUNET_NO) | ||
1726 | return; | ||
1727 | } | ||
1728 | else | ||
1729 | { | ||
1730 | scan_and_compress_trail (trail, trail_length, peer); | ||
1731 | invert_trail_list (trail, trail_length); | ||
1732 | } | ||
1733 | FPRINTF (stderr,_("\nSUPU %s, %s, %d"),__FILE__, __func__,__LINE__); | ||
1734 | memcpy (&(new_finger_entry->finger_identity), peer, sizeof (struct GNUNET_PeerIdentity)); | ||
1735 | new_finger_entry->finger_map_index = PREDECESSOR_FINGER_ID; | ||
1736 | new_finger_entry->first_trail_length = trail_length; | ||
1737 | i = 0; | ||
1738 | while (i < trail_length) | ||
1739 | { | 1786 | { |
1740 | struct TrailPeerList *element; | 1787 | while (i < trail_length) |
1741 | element = GNUNET_malloc (sizeof (struct TrailPeerList)); | 1788 | { |
1742 | element->next = NULL; | 1789 | struct TrailPeerList *element; |
1743 | element->prev = NULL; | 1790 | element = GNUNET_malloc (sizeof (struct TrailPeerList)); |
1791 | element->next = NULL; | ||
1792 | element->prev = NULL; | ||
1744 | 1793 | ||
1745 | memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity)); | 1794 | memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity)); |
1746 | GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->first_trail_head, new_finger_entry->first_trail_tail, element); | 1795 | GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element); |
1747 | i++; | 1796 | i++; |
1748 | } | 1797 | } |
1749 | 1798 | } | |
1750 | GNUNET_assert (GNUNET_OK == | 1799 | existing_finger->trail_count++; |
1751 | GNUNET_CONTAINER_multipeermap_put (finger_peermap, | ||
1752 | &(new_finger_entry->finger_identity), | ||
1753 | &new_finger_entry, | ||
1754 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); | ||
1755 | |||
1756 | return; | ||
1757 | } | 1800 | } |
1758 | 1801 | ||
1759 | 1802 | ||
@@ -1823,89 +1866,108 @@ void select_and_replace_trail (struct FingerInfo *existing_finger, | |||
1823 | 1866 | ||
1824 | 1867 | ||
1825 | /** | 1868 | /** |
1826 | * Add a new trail to reach an existing finger in finger peermap. | 1869 | * FIXME: If we remove a finger which is our friend, then do we need to handle it |
1827 | * @param existing_finger | 1870 | * differentlty in regard to trail count. |
1828 | * @param trail | 1871 | * Decrement the trail count for the first friend to reach to the finger. |
1829 | * @param trail_length | 1872 | * @param finger |
1830 | */ | 1873 | */ |
1831 | static | 1874 | static void |
1832 | void add_new_trail (struct FingerInfo *existing_finger, | 1875 | decrement_friend_trail_count (struct FingerInfo *finger) |
1833 | struct GNUNET_PeerIdentity *trail, | ||
1834 | unsigned int trail_length) | ||
1835 | { | 1876 | { |
1836 | int i; | 1877 | struct FriendInfo *first_trail_friend; |
1837 | i = 0; | 1878 | struct FriendInfo *second_trail_friend; |
1838 | 1879 | ||
1839 | if (existing_finger->second_trail_head != NULL) | 1880 | if(finger->first_trail_head != NULL) |
1840 | { | 1881 | { |
1841 | while (i < trail_length) | 1882 | first_trail_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, |
1842 | { | 1883 | &(finger->first_trail_head->peer)); |
1843 | struct TrailPeerList *element; | 1884 | first_trail_friend->trails_count--; |
1844 | element = GNUNET_malloc (sizeof (struct TrailPeerList)); | 1885 | } |
1845 | element->next = NULL; | ||
1846 | element->prev = NULL; | ||
1847 | 1886 | ||
1848 | memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity)); | 1887 | if(finger->second_trail_head != NULL) |
1849 | GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element); | 1888 | { |
1850 | i++; | 1889 | second_trail_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, |
1851 | } | 1890 | &(finger->second_trail_head->peer)); |
1891 | second_trail_friend->trails_count--; | ||
1852 | } | 1892 | } |
1853 | else if (existing_finger->second_trail_head != NULL) | 1893 | |
1894 | if (GNUNET_YES == all_friends_trail_threshold) | ||
1854 | { | 1895 | { |
1855 | while (i < trail_length) | 1896 | all_friends_trail_threshold = GNUNET_NO; |
1856 | { | 1897 | /* FIXME; Here you should reschedule the send_find_finger_task here. or |
1857 | struct TrailPeerList *element; | 1898 | make a call.*/ |
1858 | element = GNUNET_malloc (sizeof (struct TrailPeerList)); | 1899 | } |
1859 | element->next = NULL; | ||
1860 | element->prev = NULL; | ||
1861 | |||
1862 | memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity)); | ||
1863 | GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element); | ||
1864 | i++; | ||
1865 | } | ||
1866 | } | ||
1867 | } | 1900 | } |
1868 | 1901 | ||
1869 | 1902 | ||
1870 | /** | 1903 | /** |
1871 | * * 1.* If you remove an entry from finger table, and if the finger is not your friend | 1904 | * FIXME: consider the case where my_id = 2, and we are in circle from 0 to 7. |
1872 | * and the trail length > 1 for the finger that you removed, then you should send | 1905 | * my current_predecessor is 6, and now the new finger 1. Here we are checking |
1873 | * a trail_teardown message along the trail. so that the peers which have an | 1906 | * if existing_finger < new_entry then new_entry is predecessor. This holds |
1874 | * entry in their routing table for this trail can remove it from their routing | 1907 | * true in case where lets say existing_finger = 5, new_entry= 6. But in the case |
1875 | * table. | 1908 | * above, 6 > 1 but still 1 is correct predecessor. We have not handled it here. |
1876 | * Better name | 1909 | * We can put all the three values in an array and then the peer just before me |
1877 | * TODO: First check if both the trails are present if yes then send it | 1910 | * will be mine predecessor. |
1878 | * for both of them. | 1911 | * FIXME: Currently I am using struct Sorting_list to compare the values, |
1912 | * will create a new ds if needed. | ||
1879 | * @param existing_finger | 1913 | * @param existing_finger |
1914 | * @param new_finger | ||
1915 | * @return | ||
1880 | */ | 1916 | */ |
1881 | static | 1917 | static |
1882 | void send_trail_teardown (struct FingerInfo *existing_finger) | 1918 | int select_finger (struct FingerInfo *existing_finger, |
1919 | const struct GNUNET_PeerIdentity *new_finger, | ||
1920 | unsigned int finger_map_index) | ||
1883 | { | 1921 | { |
1884 | struct GNUNET_PeerIdentity *peer_list; | 1922 | struct Sorting_List peers[3]; /* 3 for existing_finger, new_finger, my_identity */ |
1885 | struct FriendInfo *friend; | 1923 | struct Sorting_List *closest_finger; |
1886 | struct TrailPeerList *finger_trail; | 1924 | uint64_t value; |
1887 | int existing_finger_trail_length = existing_finger->first_trail_length; | 1925 | int k; |
1888 | int i = 0; | 1926 | |
1889 | 1927 | for (k = 0; k < 3; k++) | |
1890 | 1928 | peers[k].data = 0; | |
1891 | finger_trail = existing_finger->first_trail_head; | 1929 | |
1892 | friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(finger_trail->peer)); | 1930 | memcpy (&peers[0], &my_identity, sizeof (uint64_t)); |
1893 | peer_list = GNUNET_malloc ( existing_finger_trail_length * sizeof (struct GNUNET_PeerIdentity)); | 1931 | peers[0].type = MY_ID; |
1894 | while (i < existing_finger->first_trail_length) | 1932 | peers[0].data = NULL; |
1895 | { | 1933 | |
1896 | memcpy (&peer_list[i], &(finger_trail->peer), sizeof (struct GNUNET_PeerIdentity)); | 1934 | memcpy (&peers[1], &(existing_finger->finger_identity), sizeof (uint64_t)); |
1897 | finger_trail = finger_trail->next; | 1935 | peers[1].type = FINGER; |
1898 | i++; | 1936 | peers[1].data = existing_finger; |
1899 | } | 1937 | |
1900 | 1938 | memcpy (&peers[2], &new_finger, sizeof (uint64_t)); | |
1901 | GDS_NEIGHBOURS_send_trail_teardown (&my_identity, &(existing_finger->finger_identity), | 1939 | peers[2].type = VALUE; |
1902 | peer_list, existing_finger_trail_length, friend); | 1940 | peers[2].data = NULL; |
1941 | |||
1942 | memcpy (&value, &my_identity, sizeof (uint64_t)); | ||
1943 | |||
1944 | |||
1945 | qsort (&peers, 3, sizeof (struct Sorting_List), &compare_peer_id); | ||
1946 | |||
1947 | if (PREDECESSOR_FINGER_ID == finger_map_index) | ||
1948 | closest_finger = find_closest_predecessor (peers, value, 3); | ||
1949 | else | ||
1950 | closest_finger = find_closest_successor (peers, value, 3); | ||
1951 | |||
1952 | if (closest_finger->type == FINGER) | ||
1953 | { | ||
1954 | return GNUNET_NO; | ||
1955 | } | ||
1956 | else if (closest_finger->type == VALUE) | ||
1957 | { | ||
1958 | return GNUNET_YES; | ||
1959 | } | ||
1960 | else if (closest_finger->type == MY_ID); | ||
1961 | { | ||
1962 | return GNUNET_SYSERR; | ||
1963 | } | ||
1903 | } | 1964 | } |
1904 | 1965 | ||
1905 | 1966 | ||
1906 | /**TOD0. | 1967 | /** |
1907 | * Choose the closest successor from existing_finger and new_finger. In case new_finger | 1968 | * Choose the closest finger between existing_finger and new_finger. In case new_finger |
1908 | * is choosen, then send a tear down message along the trail to reach existing_finger. | 1969 | * is closest and finger_map_index != PREDCESSOR_FINGER_ID, |
1970 | * then send a tear down message along the trail to reach existing_finger. | ||
1909 | * @param existing_finger Existing entry in finger peer map | 1971 | * @param existing_finger Existing entry in finger peer map |
1910 | * @param new_finger New finger | 1972 | * @param new_finger New finger |
1911 | * @param trail Trail to reach to the new finger from me. | 1973 | * @param trail Trail to reach to the new finger from me. |
@@ -1921,16 +1983,23 @@ static | |||
1921 | int select_closest_finger (struct FingerInfo *existing_finger, | 1983 | int select_closest_finger (struct FingerInfo *existing_finger, |
1922 | const struct GNUNET_PeerIdentity *new_finger, | 1984 | const struct GNUNET_PeerIdentity *new_finger, |
1923 | struct GNUNET_PeerIdentity *trail, | 1985 | struct GNUNET_PeerIdentity *trail, |
1924 | unsigned int trail_length) | 1986 | unsigned int trail_length, |
1987 | unsigned int finger_map_index) | ||
1925 | { | 1988 | { |
1926 | int val = GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), new_finger); | ||
1927 | 1989 | ||
1928 | if (0 == val) | 1990 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), new_finger)) |
1929 | { | 1991 | { |
1930 | /*FIXME: Check if this returns the compressed trail in the trail sent as parameter. | 1992 | /* Both the new entry and existing entry are same. */ |
1931 | Scan the trail for a friend and shorten if possible. */ | 1993 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), &my_identity)) |
1932 | scan_and_compress_trail (trail, trail_length, new_finger); | 1994 | { |
1933 | 1995 | /* If both are same then exit. You already have that entry in your finger table, | |
1996 | then you don't need to add it again. */ | ||
1997 | return GNUNET_NO; | ||
1998 | } | ||
1999 | if (trail_length > 1) | ||
2000 | { | ||
2001 | scan_and_compress_trail (trail, &trail_length, new_finger); | ||
2002 | } | ||
1934 | if (existing_finger->trail_count < TRAIL_COUNT) | 2003 | if (existing_finger->trail_count < TRAIL_COUNT) |
1935 | { | 2004 | { |
1936 | add_new_trail (existing_finger, trail, trail_length); | 2005 | add_new_trail (existing_finger, trail, trail_length); |
@@ -1938,24 +2007,36 @@ int select_closest_finger (struct FingerInfo *existing_finger, | |||
1938 | } | 2007 | } |
1939 | else | 2008 | else |
1940 | { | 2009 | { |
1941 | /* If not then first check if this new trail is shorter than other trails, | ||
1942 | if yes then remove the old trail, and add this new trail. and send GNUNET_YES. */ | ||
1943 | select_and_replace_trail (existing_finger, trail, trail_length); | 2010 | select_and_replace_trail (existing_finger, trail, trail_length); |
1944 | return GNUNET_NO; | 2011 | return GNUNET_NO; |
1945 | } | 2012 | } |
1946 | } | 2013 | } |
1947 | else if (val > 0) | 2014 | else if (GNUNET_YES == select_finger (existing_finger, new_finger, finger_map_index)) |
1948 | { | 2015 | { |
1949 | /* If the new entry is closest one, then free the old entry, send a trail_teardown message.*/ | 2016 | /* Here in case finger_map_index was Predecessor_finger then also you don't |
2017 | need to send trail teardown and in case its successor then you found it in | ||
2018 | trail_setup and then you don't need to send trail teardown. FIXME: check if | ||
2019 | its true for every call made to finger_table_add. Also, if we have an entry | ||
2020 | which is not my identity should I replace it with my identity or not? */ | ||
2021 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, new_finger)) | ||
2022 | { | ||
2023 | return GNUNET_NO; /* FIXME: In case I have a peer id which is not my id then | ||
2024 | * should I keep it as finger */ | ||
2025 | |||
2026 | } | ||
2027 | /* new_finger is the correct finger. */ | ||
2028 | if (PREDECESSOR_FINGER_ID != finger_map_index) | ||
2029 | send_trail_teardown (existing_finger); | ||
1950 | 2030 | ||
1951 | send_trail_teardown (existing_finger); | 2031 | decrement_friend_trail_count (existing_finger); |
1952 | free_finger (existing_finger); | 2032 | free_finger (existing_finger); |
1953 | scan_and_compress_trail (trail, trail_length, new_finger); | 2033 | if (trail_length > 1) |
2034 | scan_and_compress_trail (trail, &trail_length, new_finger); | ||
1954 | return GNUNET_YES; | 2035 | return GNUNET_YES; |
1955 | } | 2036 | } |
1956 | else | 2037 | else if (GNUNET_NO == select_finger (existing_finger, new_finger,finger_map_index)) |
1957 | { | 2038 | { |
1958 | /* If the old entry is closest then just return GNUNET_NO.*/ | 2039 | /* existing_finger is the correct finger. */ |
1959 | return GNUNET_NO; | 2040 | return GNUNET_NO; |
1960 | } | 2041 | } |
1961 | return GNUNET_SYSERR; | 2042 | return GNUNET_SYSERR; |
@@ -1963,18 +2044,117 @@ int select_closest_finger (struct FingerInfo *existing_finger, | |||
1963 | 2044 | ||
1964 | 2045 | ||
1965 | /** | 2046 | /** |
2047 | * Check if there is a predecessor in our finger peer map or not. | ||
2048 | * If no, then return GNUNET_YES | ||
2049 | * else compare existing predecessor and peer, and find the correct | ||
2050 | * predecessor. | ||
2051 | * @param existing_predecessor | ||
2052 | * @param new_predecessor | ||
2053 | * @return #GNUNET_YES if new peer is predecessor | ||
2054 | * #GNUNET_NO if new peer is not the predecessor. | ||
2055 | */ | ||
2056 | static int | ||
2057 | compare_and_update_predecessor (const struct GNUNET_PeerIdentity *peer, | ||
2058 | struct GNUNET_PeerIdentity *trail, | ||
2059 | unsigned int trail_length) | ||
2060 | { | ||
2061 | /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */ | ||
2062 | struct FingerInfo *existing_finger; | ||
2063 | struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; | ||
2064 | struct FingerInfo *new_finger_entry; | ||
2065 | struct FriendInfo *first_friend_trail; | ||
2066 | int i; | ||
2067 | |||
2068 | finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); | ||
2069 | for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++) | ||
2070 | { | ||
2071 | if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, NULL, | ||
2072 | (const void **)&existing_finger)) | ||
2073 | { | ||
2074 | if (PREDECESSOR_FINGER_ID == existing_finger->finger_map_index) | ||
2075 | { | ||
2076 | if( GNUNET_NO == select_closest_finger (existing_finger, peer, trail, | ||
2077 | trail_length,PREDECESSOR_FINGER_ID)) | ||
2078 | return GNUNET_NO; | ||
2079 | else | ||
2080 | break; | ||
2081 | } | ||
2082 | } | ||
2083 | } | ||
2084 | GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); | ||
2085 | |||
2086 | new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo)); | ||
2087 | memcpy (&(new_finger_entry->finger_identity), peer, sizeof (struct GNUNET_PeerIdentity)); | ||
2088 | new_finger_entry->finger_map_index = PREDECESSOR_FINGER_ID; | ||
2089 | new_finger_entry->first_trail_length = trail_length; | ||
2090 | |||
2091 | if (trail != NULL) /* finger_trail is NULL in case I am my own finger identity. */ | ||
2092 | { | ||
2093 | /* FIXME: Currently we are not handling the second trail. In that case, finger | ||
2094 | trail count = min (first_friend, second_friend) trail count. */ | ||
2095 | /* Incrementing the friend trails count. */ | ||
2096 | if (trail_length > 0) | ||
2097 | { | ||
2098 | first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[0]); | ||
2099 | first_friend_trail->trails_count++; | ||
2100 | } | ||
2101 | else | ||
2102 | { | ||
2103 | /* It means the finger is my friend. */ | ||
2104 | first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer); | ||
2105 | first_friend_trail->trails_count++; | ||
2106 | } | ||
2107 | new_finger_entry->first_friend_trails_count = first_friend_trail->trails_count; | ||
2108 | |||
2109 | if (trail_length != 0) | ||
2110 | { | ||
2111 | i = trail_length - 1; | ||
2112 | while (i > 0) | ||
2113 | { | ||
2114 | struct TrailPeerList *element; | ||
2115 | element = GNUNET_malloc (sizeof (struct TrailPeerList)); | ||
2116 | element->next = NULL; | ||
2117 | element->prev = NULL; | ||
2118 | |||
2119 | memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity)); | ||
2120 | GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->first_trail_head, new_finger_entry->first_trail_tail, element); | ||
2121 | i--; | ||
2122 | } | ||
2123 | struct TrailPeerList *element; | ||
2124 | element = GNUNET_malloc (sizeof (struct TrailPeerList)); | ||
2125 | element->next = NULL; | ||
2126 | element->prev = NULL; | ||
2127 | memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity)); | ||
2128 | GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->first_trail_head, new_finger_entry->first_trail_tail, element); | ||
2129 | } | ||
2130 | } | ||
2131 | GNUNET_assert (GNUNET_OK == | ||
2132 | GNUNET_CONTAINER_multipeermap_put (finger_peermap, | ||
2133 | &(new_finger_entry->finger_identity), | ||
2134 | new_finger_entry, | ||
2135 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); | ||
2136 | |||
2137 | return GNUNET_YES; | ||
2138 | } | ||
2139 | |||
2140 | |||
2141 | /** | ||
1966 | * FIXME: Better name, and make the code more cleaner. | 2142 | * FIXME: Better name, and make the code more cleaner. |
1967 | * Compare the new finger entry added and our successor. | 2143 | * Compare the new finger entry added and our successor. |
1968 | * @return #GNUNET_YES if same. | 2144 | * @return #GNUNET_YES if same. |
1969 | * #GNUNET_NO if not. | 2145 | * #GNUNET_NO if not. |
1970 | */ | 2146 | */ |
1971 | static int | 2147 | static int |
1972 | compare_new_entry_successor (const struct GNUNET_PeerIdentity *new_finger) | 2148 | compare_new_entry_and_successor (const struct GNUNET_PeerIdentity *new_finger, |
2149 | int finger_map_index) | ||
1973 | { | 2150 | { |
1974 | int successor_flag = 0; | 2151 | int successor_flag = 0; |
1975 | struct FingerInfo *successor_finger; | 2152 | struct FingerInfo *successor_finger; |
1976 | struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; | 2153 | struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; |
1977 | int i; | 2154 | int i; |
2155 | |||
2156 | if (PREDECESSOR_FINGER_ID == finger_map_index) | ||
2157 | return GNUNET_NO; | ||
1978 | 2158 | ||
1979 | finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); | 2159 | finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); |
1980 | for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++) | 2160 | for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++) |
@@ -1989,6 +2169,8 @@ compare_new_entry_successor (const struct GNUNET_PeerIdentity *new_finger) | |||
1989 | } | 2169 | } |
1990 | } | 2170 | } |
1991 | } | 2171 | } |
2172 | GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); | ||
2173 | |||
1992 | /* Ideally we should never reach here. */ | 2174 | /* Ideally we should never reach here. */ |
1993 | if (successor_flag == 0) | 2175 | if (successor_flag == 0) |
1994 | { | 2176 | { |
@@ -2004,6 +2186,8 @@ compare_new_entry_successor (const struct GNUNET_PeerIdentity *new_finger) | |||
2004 | 2186 | ||
2005 | 2187 | ||
2006 | /** | 2188 | /** |
2189 | * FIXME: ensure that function sending finger_table_add checks if source and your | ||
2190 | * identity is same, if yes then set trail_list to NULL and trail length = 0. | ||
2007 | * Add an entry in the finger table. If there is already an existing entry in | 2191 | * Add an entry in the finger table. If there is already an existing entry in |
2008 | * the finger peermap for given finger map index, then choose the closest one. | 2192 | * the finger peermap for given finger map index, then choose the closest one. |
2009 | * In case both the new entry and old entry are same, store both of them. (Redundant | 2193 | * In case both the new entry and old entry are same, store both of them. (Redundant |
@@ -2012,25 +2196,26 @@ compare_new_entry_successor (const struct GNUNET_PeerIdentity *new_finger) | |||
2012 | * @param finger_trail | 2196 | * @param finger_trail |
2013 | * @param finger_trail_length | 2197 | * @param finger_trail_length |
2014 | * @param finger_map_index | 2198 | * @param finger_map_index |
2199 | * @return #GNUNET_YES if the new entry is added. | ||
2200 | * #GNUNET_NO if the new entry is discarded. | ||
2015 | */ | 2201 | */ |
2016 | static | 2202 | static |
2017 | void finger_table_add (const struct GNUNET_PeerIdentity *finger_identity, | 2203 | int finger_table_add (const struct GNUNET_PeerIdentity *finger_identity, |
2018 | struct GNUNET_PeerIdentity *finger_trail, | 2204 | struct GNUNET_PeerIdentity *finger_trail, |
2019 | uint32_t finger_trail_length, | 2205 | uint32_t finger_trail_length, |
2020 | uint32_t finger_map_index) | 2206 | uint32_t finger_map_index) |
2021 | { | 2207 | { |
2022 | struct FingerInfo new_finger_entry; | 2208 | struct FingerInfo *new_finger_entry; |
2023 | struct FingerInfo *existing_finger; | 2209 | struct FingerInfo *existing_finger; |
2024 | struct FriendInfo *first_friend_trail; | 2210 | struct FriendInfo *first_friend_trail; |
2025 | struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; | 2211 | struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; |
2212 | int new_entry_added_flag = 0; | ||
2026 | int i; | 2213 | int i; |
2027 | 2214 | ||
2028 | /* If you are your own finger, then exit. */ | 2215 | if (PREDECESSOR_FINGER_ID == finger_map_index) |
2029 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, finger_identity)) | ||
2030 | { | 2216 | { |
2031 | /* SUPU: We don't store this trail in case of trail_setup_result, if | 2217 | compare_and_update_predecessor (finger_identity, finger_trail, finger_trail_length); |
2032 | source and destination of the message are same. */ | 2218 | goto update_current_search_finger_index; |
2033 | return; | ||
2034 | } | 2219 | } |
2035 | 2220 | ||
2036 | /* Check if there is already an entry for the finger map index in the finger peer map. */ | 2221 | /* Check if there is already an entry for the finger map index in the finger peer map. */ |
@@ -2042,160 +2227,107 @@ void finger_table_add (const struct GNUNET_PeerIdentity *finger_identity, | |||
2042 | { | 2227 | { |
2043 | if (existing_finger->finger_map_index == finger_map_index) | 2228 | if (existing_finger->finger_map_index == finger_map_index) |
2044 | { | 2229 | { |
2045 | /* If existing finger is closest or both the new finger and existing finger | ||
2046 | are same, then just update current_search_finger_index. We are not | ||
2047 | adding a new entry just updating the existing entry or doing nothing. */ | ||
2048 | if ( GNUNET_NO == select_closest_finger (existing_finger, finger_identity, | 2230 | if ( GNUNET_NO == select_closest_finger (existing_finger, finger_identity, |
2049 | finger_trail, finger_trail_length)) | 2231 | finger_trail, finger_trail_length,finger_map_index)) |
2050 | goto update_current_search_finger_index; | 2232 | goto update_current_search_finger_index; |
2051 | else | 2233 | else |
2052 | break; | 2234 | break; |
2053 | } | 2235 | } |
2054 | } | 2236 | } |
2055 | } | 2237 | } |
2238 | GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); | ||
2056 | 2239 | ||
2057 | /* Add the new entry. */ | 2240 | /* Add a new entry. */ |
2058 | memcpy (&(new_finger_entry.finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity)); | 2241 | new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo)); |
2059 | new_finger_entry.finger_map_index = finger_map_index; | 2242 | memcpy (&(new_finger_entry->finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity)); |
2060 | new_finger_entry.first_trail_length = finger_trail_length; | 2243 | new_finger_entry->finger_map_index = finger_map_index; |
2061 | 2244 | new_finger_entry->first_trail_length = finger_trail_length; | |
2062 | if (finger_trail_length > 0) | 2245 | new_finger_entry->trail_count = 1; |
2063 | { | ||
2064 | first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_trail[0]); | ||
2065 | first_friend_trail->trails_count++; | ||
2066 | } | ||
2067 | else | ||
2068 | { | ||
2069 | /* It means the finger is my friend. */ | ||
2070 | first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, finger_identity); | ||
2071 | first_friend_trail->trails_count++; | ||
2072 | } | ||
2073 | |||
2074 | 2246 | ||
2075 | new_finger_entry.first_friend_trails_count = first_friend_trail->trails_count; | 2247 | if (finger_trail != NULL) /* finger_trail is NULL in case I am my own finger identity. */ |
2076 | i = 0; | ||
2077 | while (i < finger_trail_length) | ||
2078 | { | 2248 | { |
2079 | struct TrailPeerList *element; | 2249 | /* FIXME: Currently we are not handling the second trail. In that case, finger |
2080 | element = GNUNET_malloc (sizeof (struct TrailPeerList)); | 2250 | trail count = min (first_friend, second_friend) trail count. */ |
2081 | element->next = NULL; | 2251 | /* Incrementing the friend trails count. */ |
2082 | element->prev = NULL; | 2252 | if (finger_trail_length > 0) |
2253 | { | ||
2254 | first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_trail[0]); | ||
2255 | first_friend_trail->trails_count++; | ||
2256 | } | ||
2257 | else | ||
2258 | { | ||
2259 | /* It means the finger is my friend. */ | ||
2260 | first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, finger_identity); | ||
2261 | first_friend_trail->trails_count++; | ||
2262 | } | ||
2263 | new_finger_entry->first_friend_trails_count = first_friend_trail->trails_count; | ||
2083 | 2264 | ||
2084 | memcpy (&(element->peer), &finger_trail[i], sizeof(struct GNUNET_PeerIdentity)); | 2265 | /* Copy the trail. */ |
2085 | GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry.first_trail_head, new_finger_entry.first_trail_tail, element); | 2266 | i = 0; |
2086 | i++; | 2267 | while (i < finger_trail_length) |
2268 | { | ||
2269 | struct TrailPeerList *element; | ||
2270 | element = GNUNET_malloc (sizeof (struct TrailPeerList)); | ||
2271 | element->next = NULL; | ||
2272 | element->prev = NULL; | ||
2273 | |||
2274 | memcpy (&(element->peer), &finger_trail[i], sizeof(struct GNUNET_PeerIdentity)); | ||
2275 | GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->first_trail_head, new_finger_entry->first_trail_tail, element); | ||
2276 | i++; | ||
2277 | } | ||
2087 | } | 2278 | } |
2088 | 2279 | ||
2280 | new_entry_added_flag = 1; | ||
2089 | GNUNET_assert (GNUNET_OK == | 2281 | GNUNET_assert (GNUNET_OK == |
2090 | GNUNET_CONTAINER_multipeermap_put (finger_peermap, | 2282 | GNUNET_CONTAINER_multipeermap_put (finger_peermap, |
2091 | &(new_finger_entry.finger_identity), | 2283 | &(new_finger_entry->finger_identity), |
2092 | &new_finger_entry, | 2284 | new_finger_entry, |
2093 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); | 2285 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); |
2094 | 2286 | ||
2095 | /* Set the value of current_search_finger_index. */ | 2287 | /* Update the value of current_search_finger_index. */ |
2096 | update_current_search_finger_index: | 2288 | update_current_search_finger_index: |
2097 | if (0 == finger_map_index) | 2289 | if (0 == finger_map_index ) |
2098 | { | 2290 | { |
2099 | verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL); | ||
2100 | current_search_finger_index = PREDECESSOR_FINGER_ID; | 2291 | current_search_finger_index = PREDECESSOR_FINGER_ID; |
2101 | return; | 2292 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,&(new_finger_entry->finger_identity))) |
2293 | verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL); | ||
2102 | } | 2294 | } |
2103 | else if (GNUNET_YES == compare_new_entry_successor (finger_identity)) | 2295 | else if (GNUNET_YES == compare_new_entry_and_successor (finger_identity,finger_map_index)) |
2104 | { | 2296 | { |
2105 | /* If the new entry is same as our successor, then reset the current_search_finger_index to 0*/ | 2297 | /* If the new entry is same as our successor, then reset the current_search_finger_index to 0*/ |
2106 | current_search_finger_index = 0; | 2298 | current_search_finger_index = 0; |
2107 | return; | ||
2108 | } | 2299 | } |
2109 | else | 2300 | else |
2110 | { | 2301 | { |
2111 | current_search_finger_index = current_search_finger_index - 1; | 2302 | current_search_finger_index = current_search_finger_index - 1; |
2112 | return; | ||
2113 | } | 2303 | } |
2114 | } | ||
2115 | |||
2116 | |||
2117 | /** | ||
2118 | * Compare two peer identities. | ||
2119 | * @param p1 Peer identity | ||
2120 | * @param p2 Peer identity | ||
2121 | * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2. | ||
2122 | */ | ||
2123 | static int | ||
2124 | compare_peer_id (const void *p1, const void *p2) | ||
2125 | { | ||
2126 | struct Sorting_List *p11; | ||
2127 | struct Sorting_List *p22; | ||
2128 | int ret; | ||
2129 | p11 = GNUNET_malloc (sizeof (struct Sorting_List)); | ||
2130 | p22 = GNUNET_malloc (sizeof (struct Sorting_List)); | ||
2131 | p11 = (struct Sorting_List *)p1; | ||
2132 | p22 = (struct Sorting_List *)p2; | ||
2133 | ret = ( (p11->peer_id) > (p22->peer_id) ) ? 1 : | ||
2134 | ( (p11->peer_id) == (p22->peer_id) ) ? 0 : -1; | ||
2135 | return ret; | ||
2136 | } | ||
2137 | |||
2138 | |||
2139 | /** | ||
2140 | * Return the successor of value in all_known_peers. | ||
2141 | * @param all_known_peers list of all the peers | ||
2142 | * @param value value we have to search in the all_known_peers. | ||
2143 | * @return | ||
2144 | */ | ||
2145 | static struct Sorting_List * | ||
2146 | find_closest_successor(struct Sorting_List *all_known_peers, uint64_t value, | ||
2147 | unsigned int size) | ||
2148 | { | ||
2149 | int first; | ||
2150 | int last; | ||
2151 | int middle; | ||
2152 | |||
2153 | first = 0; | ||
2154 | last = size - 1; | ||
2155 | middle = (first + last)/2; | ||
2156 | 2304 | ||
2157 | while(first <= last) | 2305 | if (1 == new_entry_added_flag) |
2158 | { | 2306 | return GNUNET_YES; |
2159 | if(all_known_peers[middle].peer_id < value) | 2307 | else |
2160 | { | 2308 | return GNUNET_NO; |
2161 | first = middle + 1; | ||
2162 | } | ||
2163 | else if(all_known_peers[middle].peer_id == value) | ||
2164 | { | ||
2165 | if(middle == (size -1)) | ||
2166 | { | ||
2167 | return &all_known_peers[0]; | ||
2168 | } | ||
2169 | else | ||
2170 | { | ||
2171 | return &all_known_peers[middle+1]; | ||
2172 | } | ||
2173 | } | ||
2174 | else | ||
2175 | { | ||
2176 | last = middle - 1; | ||
2177 | } | ||
2178 | |||
2179 | middle = (first + last)/2; | ||
2180 | } | ||
2181 | return NULL; | ||
2182 | } | 2309 | } |
2183 | 2310 | ||
2184 | 2311 | ||
2185 | /** | 2312 | /** |
2313 | * FIXME: In case a friend is either congested or has crossed its trail threshold, | ||
2314 | * then don't consider it as next successor, In case of finger if its first | ||
2315 | * friend has crossed the threshold then don't consider it. In case no finger | ||
2316 | * or friend is found, then return NULL. | ||
2186 | * Find closest successor for the value. | 2317 | * Find closest successor for the value. |
2187 | * @param value Value for which we are looking for successor | 2318 | * @param value Value for which we are looking for successor |
2188 | * @param[out] current_destination set to the end of the finger to traverse next | 2319 | * @param[out] current_destination set to my_identity in case I am the final destination, |
2320 | * set to friend identity in case friend is final destination, | ||
2321 | * set to first friend to reach to finger, in case finger | ||
2322 | * is final destination. | ||
2189 | * @param[out] current_source set to my_identity. | 2323 | * @param[out] current_source set to my_identity. |
2190 | * @param congested_peer Peer not to be considered when looking for | 2324 | * @return Peer identity of next hop to send trail setup message to, |
2191 | * successor. FIXME: IMPLEMENT IT. | 2325 | * NULL in case all the friends are either congested or have crossed |
2192 | * @return Peer identity of next hop, NULL if we are the | 2326 | * their trail threshold. |
2193 | * ultimate destination | ||
2194 | */ | 2327 | */ |
2195 | static struct GNUNET_PeerIdentity * | 2328 | static struct GNUNET_PeerIdentity * |
2196 | find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination, | 2329 | find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination, |
2197 | struct GNUNET_PeerIdentity *current_source, | 2330 | struct GNUNET_PeerIdentity *current_source) |
2198 | struct GNUNET_PeerIdentity *congested_peer) | ||
2199 | { | 2331 | { |
2200 | struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter; | 2332 | struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter; |
2201 | struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; | 2333 | struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter; |
@@ -2245,6 +2377,7 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination, | |||
2245 | } | 2377 | } |
2246 | } | 2378 | } |
2247 | 2379 | ||
2380 | |||
2248 | /* Iterate over finger map and copy all the entries into all_known_peers array. */ | 2381 | /* Iterate over finger map and copy all the entries into all_known_peers array. */ |
2249 | finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); | 2382 | finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); |
2250 | for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++) | 2383 | for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++) |
@@ -2259,8 +2392,9 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination, | |||
2259 | } | 2392 | } |
2260 | 2393 | ||
2261 | GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); | 2394 | GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); |
2262 | GNUNET_CONTAINER_multipeermap_iterator_destroy (friend_iter); | 2395 | GNUNET_CONTAINER_multipeermap_iterator_destroy (friend_iter); |
2263 | 2396 | ||
2397 | |||
2264 | qsort (&all_known_peers, size, sizeof (struct Sorting_List), &compare_peer_id); | 2398 | qsort (&all_known_peers, size, sizeof (struct Sorting_List), &compare_peer_id); |
2265 | 2399 | ||
2266 | /* search value in all_known_peers array. */ | 2400 | /* search value in all_known_peers array. */ |
@@ -2268,8 +2402,6 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination, | |||
2268 | 2402 | ||
2269 | if (successor->type == MY_ID) | 2403 | if (successor->type == MY_ID) |
2270 | { | 2404 | { |
2271 | /* FIXME: make sure everywhere you are using current_destination to check if | ||
2272 | I am the final destination. */ | ||
2273 | memcpy (current_destination, &my_identity, sizeof (struct GNUNET_PeerIdentity)); | 2405 | memcpy (current_destination, &my_identity, sizeof (struct GNUNET_PeerIdentity)); |
2274 | return NULL; | 2406 | return NULL; |
2275 | } | 2407 | } |
@@ -2285,20 +2417,25 @@ find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination, | |||
2285 | { | 2417 | { |
2286 | struct GNUNET_PeerIdentity *next_hop; | 2418 | struct GNUNET_PeerIdentity *next_hop; |
2287 | struct FingerInfo *finger; | 2419 | struct FingerInfo *finger; |
2288 | struct TrailPeerList *iterator; | ||
2289 | iterator = GNUNET_malloc (sizeof (struct TrailPeerList)); | ||
2290 | finger = successor->data; | 2420 | finger = successor->data; |
2291 | iterator = finger->first_trail_head; | ||
2292 | next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); | 2421 | next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); |
2293 | memcpy (next_hop, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity)); | 2422 | |
2423 | if (finger->first_trail_length > 0) | ||
2424 | { | ||
2425 | struct TrailPeerList *iterator; | ||
2426 | iterator = GNUNET_malloc (sizeof (struct TrailPeerList)); | ||
2427 | iterator = finger->first_trail_head; | ||
2428 | memcpy (next_hop, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity)); | ||
2429 | } | ||
2430 | else /* This means finger is our friend. */ | ||
2431 | memcpy (next_hop, &(finger->finger_identity), sizeof(struct GNUNET_PeerIdentity)); | ||
2432 | |||
2294 | memcpy (current_destination, &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity)); | 2433 | memcpy (current_destination, &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity)); |
2295 | memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity)); | 2434 | memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity)); |
2296 | return next_hop; | 2435 | return next_hop; |
2297 | } | 2436 | } |
2298 | else | 2437 | else |
2299 | { | 2438 | { |
2300 | /* FIXME: This is returned when congested peer is the only peer or the only | ||
2301 | finger that we have is reachable through this congested peer. */ | ||
2302 | GNUNET_assert (0); | 2439 | GNUNET_assert (0); |
2303 | return NULL; | 2440 | return NULL; |
2304 | } | 2441 | } |
@@ -2342,7 +2479,7 @@ GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key, | |||
2342 | struct FriendInfo *target_friend; | 2479 | struct FriendInfo *target_friend; |
2343 | struct GNUNET_PeerIdentity *pp; | 2480 | struct GNUNET_PeerIdentity *pp; |
2344 | size_t msize; | 2481 | size_t msize; |
2345 | 2482 | ||
2346 | msize = put_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size + | 2483 | msize = put_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size + |
2347 | sizeof (struct PeerPutMessage); | 2484 | sizeof (struct PeerPutMessage); |
2348 | 2485 | ||
@@ -2364,19 +2501,18 @@ GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key, | |||
2364 | { | 2501 | { |
2365 | uint64_t key_value; | 2502 | uint64_t key_value; |
2366 | struct GNUNET_PeerIdentity *next_hop; | 2503 | struct GNUNET_PeerIdentity *next_hop; |
2367 | |||
2368 | memcpy (&key_value, key, sizeof (uint64_t)); | 2504 | memcpy (&key_value, key, sizeof (uint64_t)); |
2369 | struct GNUNET_PeerIdentity curr_dest; | 2505 | struct GNUNET_PeerIdentity curr_dest; |
2370 | struct GNUNET_PeerIdentity curr_src; | 2506 | struct GNUNET_PeerIdentity curr_src; |
2371 | memcpy (&curr_dest, ¤t_destination, sizeof (struct GNUNET_PeerIdentity)); | 2507 | memcpy (&curr_dest, ¤t_destination, sizeof (struct GNUNET_PeerIdentity)); |
2372 | memcpy (&curr_src, ¤t_source, sizeof (struct GNUNET_PeerIdentity)); | 2508 | memcpy (&curr_src, ¤t_source, sizeof (struct GNUNET_PeerIdentity)); |
2373 | next_hop = find_successor (key_value, &curr_dest, &curr_src, NULL); | 2509 | next_hop = find_successor (key_value, &curr_dest, &curr_src); |
2374 | /* FIXME: I am copying back current_destination and current_source. but I am not | 2510 | /* FIXME: I am copying back current_destination and current_source. but I am not |
2375 | sure, if its correct. I am doing so just to remove the code from client file.*/ | 2511 | sure, if its correct. I am doing so just to remove the code from client file.*/ |
2376 | memcpy (¤t_destination, &curr_dest, sizeof (struct GNUNET_PeerIdentity)); | 2512 | memcpy (¤t_destination, &curr_dest, sizeof (struct GNUNET_PeerIdentity)); |
2377 | memcpy (¤t_source, &curr_src, sizeof (struct GNUNET_PeerIdentity)); | 2513 | memcpy (¤t_source, &curr_src, sizeof (struct GNUNET_PeerIdentity)); |
2378 | 2514 | ||
2379 | if (NULL == next_hop) /* I am the destination do datacache_put */ | 2515 | if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity,¤t_destination)) /* I am the destination do datacache_put */ |
2380 | { | 2516 | { |
2381 | GDS_DATACACHE_handle_put (expiration_time, key, put_path_length, put_path, | 2517 | GDS_DATACACHE_handle_put (expiration_time, key, put_path_length, put_path, |
2382 | block_type, data_size, data); | 2518 | block_type, data_size, data); |
@@ -2449,7 +2585,7 @@ GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key, | |||
2449 | struct FriendInfo *target_friend; | 2585 | struct FriendInfo *target_friend; |
2450 | struct GNUNET_PeerIdentity *gp; | 2586 | struct GNUNET_PeerIdentity *gp; |
2451 | size_t msize; | 2587 | size_t msize; |
2452 | 2588 | ||
2453 | msize = sizeof (struct PeerGetMessage) + | 2589 | msize = sizeof (struct PeerGetMessage) + |
2454 | (get_path_length * sizeof (struct GNUNET_PeerIdentity)); | 2590 | (get_path_length * sizeof (struct GNUNET_PeerIdentity)); |
2455 | 2591 | ||
@@ -2470,7 +2606,7 @@ GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key, | |||
2470 | memcpy (&curr_src, ¤t_source, sizeof (struct GNUNET_PeerIdentity)); | 2606 | memcpy (&curr_src, ¤t_source, sizeof (struct GNUNET_PeerIdentity)); |
2471 | memcpy (&key_value, key, sizeof (uint64_t)); | 2607 | memcpy (&key_value, key, sizeof (uint64_t)); |
2472 | // FIXME: endianess of key_value!? | 2608 | // FIXME: endianess of key_value!? |
2473 | next_hop = find_successor (key_value, &curr_dest, &curr_src, NULL); | 2609 | next_hop = find_successor (key_value, &curr_dest, &curr_src); |
2474 | /* FIXME: Again I am copying back value of current_destination, current_source, | 2610 | /* FIXME: Again I am copying back value of current_destination, current_source, |
2475 | Think of a better solution. */ | 2611 | Think of a better solution. */ |
2476 | memcpy (¤t_destination, &curr_dest, sizeof (struct GNUNET_PeerIdentity)); | 2612 | memcpy (¤t_destination, &curr_dest, sizeof (struct GNUNET_PeerIdentity)); |
@@ -2584,7 +2720,7 @@ GDS_NEIGHBOURS_send_get_result (struct GNUNET_TIME_Absolute expiration, | |||
2584 | 2720 | ||
2585 | 2721 | ||
2586 | /** | 2722 | /** |
2587 | * Send tral rejection message to the peer which sent me a trail setup message. | 2723 | * Send trail rejection message to the peer which sent me a trail setup message. |
2588 | * @param source_peer Source peer which wants to set up the trail. | 2724 | * @param source_peer Source peer which wants to set up the trail. |
2589 | * @param finger_identity Value whose successor will be the finger of @a source_peer. | 2725 | * @param finger_identity Value whose successor will be the finger of @a source_peer. |
2590 | * @param congested_peer Peer which has send trail rejection message. | 2726 | * @param congested_peer Peer which has send trail rejection message. |
@@ -2632,9 +2768,11 @@ GDS_NEIGHBOURS_send_trail_rejection (struct GNUNET_PeerIdentity *source_peer, | |||
2632 | trail_rejection->finger_map_index = htonl(finger_map_index); | 2768 | trail_rejection->finger_map_index = htonl(finger_map_index); |
2633 | trail_rejection->trail_length = htonl (trail_length); | 2769 | trail_rejection->trail_length = htonl (trail_length); |
2634 | 2770 | ||
2635 | trail_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1]; | ||
2636 | if (trail_length != 0) | 2771 | if (trail_length != 0) |
2772 | { | ||
2773 | trail_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1]; | ||
2637 | memcpy (trail_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | 2774 | memcpy (trail_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); |
2775 | } | ||
2638 | 2776 | ||
2639 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); | 2777 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); |
2640 | GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); | 2778 | GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending); |
@@ -2687,7 +2825,7 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2687 | GNUNET_break_op (0); | 2825 | GNUNET_break_op (0); |
2688 | return GNUNET_YES; | 2826 | return GNUNET_YES; |
2689 | } | 2827 | } |
2690 | 2828 | ||
2691 | current_destination = put->current_destination; | 2829 | current_destination = put->current_destination; |
2692 | current_source = put->current_source; | 2830 | current_source = put->current_source; |
2693 | put_path = (struct GNUNET_PeerIdentity *) &put[1]; | 2831 | put_path = (struct GNUNET_PeerIdentity *) &put[1]; |
@@ -2767,7 +2905,7 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2767 | } | 2905 | } |
2768 | else | 2906 | else |
2769 | { | 2907 | { |
2770 | next_hop = find_successor (key_value, ¤t_destination, ¤t_source, NULL); | 2908 | next_hop = find_successor (key_value, ¤t_destination, ¤t_source); |
2771 | } | 2909 | } |
2772 | 2910 | ||
2773 | if (NULL == next_hop) /* I am the final destination */ | 2911 | if (NULL == next_hop) /* I am the final destination */ |
@@ -2846,7 +2984,6 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2846 | GNUNET_break_op (0); | 2984 | GNUNET_break_op (0); |
2847 | return GNUNET_YES; | 2985 | return GNUNET_YES; |
2848 | } | 2986 | } |
2849 | |||
2850 | /* Add sender to get path */ | 2987 | /* Add sender to get path */ |
2851 | struct GNUNET_PeerIdentity gp[get_length + 1]; | 2988 | struct GNUNET_PeerIdentity gp[get_length + 1]; |
2852 | memcpy (gp, get_path, get_length * sizeof (struct GNUNET_PeerIdentity)); | 2989 | memcpy (gp, get_path, get_length * sizeof (struct GNUNET_PeerIdentity)); |
@@ -2864,7 +3001,7 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2864 | } | 3001 | } |
2865 | else | 3002 | else |
2866 | { | 3003 | { |
2867 | next_hop = find_successor (key_value, ¤t_destination, ¤t_source, NULL); | 3004 | next_hop = find_successor (key_value, ¤t_destination, ¤t_source); |
2868 | } | 3005 | } |
2869 | 3006 | ||
2870 | if (NULL == next_hop) | 3007 | if (NULL == next_hop) |
@@ -2895,6 +3032,9 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2895 | 3032 | ||
2896 | 3033 | ||
2897 | /** | 3034 | /** |
3035 | * FIXME: In case of trail, we don't have source and destination part of the trail, | ||
3036 | * Check if we follow the same in case of get/put/get_result. Also, in case of | ||
3037 | * put should we do a routing table add. | ||
2898 | * Core handler for get result | 3038 | * Core handler for get result |
2899 | * @param cls closure | 3039 | * @param cls closure |
2900 | * @param peer sender of the request | 3040 | * @param peer sender of the request |
@@ -2906,8 +3046,6 @@ static int | |||
2906 | handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer, | 3046 | handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer, |
2907 | const struct GNUNET_MessageHeader *message) | 3047 | const struct GNUNET_MessageHeader *message) |
2908 | { | 3048 | { |
2909 | /* If you are the source, go back to the client file and there search for | ||
2910 | the requesting client and send back the result. */ | ||
2911 | struct PeerGetResultMessage *get_result; | 3049 | struct PeerGetResultMessage *get_result; |
2912 | struct GNUNET_PeerIdentity *get_path; | 3050 | struct GNUNET_PeerIdentity *get_path; |
2913 | struct GNUNET_PeerIdentity *put_path; | 3051 | struct GNUNET_PeerIdentity *put_path; |
@@ -2984,6 +3122,7 @@ handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2984 | 3122 | ||
2985 | 3123 | ||
2986 | /** | 3124 | /** |
3125 | * FIXME: Is all trails threshold and routing table has some link. | ||
2987 | * Core handle for PeerTrailSetupMessage. | 3126 | * Core handle for PeerTrailSetupMessage. |
2988 | * @param cls closure | 3127 | * @param cls closure |
2989 | * @param message message | 3128 | * @param message message |
@@ -3016,7 +3155,7 @@ handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3016 | 3155 | ||
3017 | trail_setup = (const struct PeerTrailSetupMessage *) message; | 3156 | trail_setup = (const struct PeerTrailSetupMessage *) message; |
3018 | trail_length = ntohl (trail_setup->trail_length); | 3157 | trail_length = ntohl (trail_setup->trail_length); |
3019 | 3158 | ||
3020 | if ((msize < sizeof (struct PeerTrailSetupMessage) + | 3159 | if ((msize < sizeof (struct PeerTrailSetupMessage) + |
3021 | trail_length * sizeof (struct GNUNET_PeerIdentity)) || | 3160 | trail_length * sizeof (struct GNUNET_PeerIdentity)) || |
3022 | (trail_length > | 3161 | (trail_length > |
@@ -3026,84 +3165,108 @@ handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3026 | return GNUNET_OK; | 3165 | return GNUNET_OK; |
3027 | } | 3166 | } |
3028 | 3167 | ||
3029 | trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_setup[1]; | 3168 | if (trail_length > 0) |
3030 | current_destination = trail_setup->current_destination; | 3169 | trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_setup[1]; |
3031 | current_source = trail_setup->current_source; | 3170 | memcpy (¤t_destination, &(trail_setup->current_destination), sizeof (struct GNUNET_PeerIdentity)); |
3032 | source = trail_setup->source_peer; | 3171 | memcpy (¤t_source,&(trail_setup->current_source), sizeof (struct GNUNET_PeerIdentity)); |
3172 | memcpy (&source, &(trail_setup->source_peer), sizeof (struct GNUNET_PeerIdentity)); | ||
3033 | finger_map_index = ntohl (trail_setup->finger_map_index); | 3173 | finger_map_index = ntohl (trail_setup->finger_map_index); |
3034 | destination_finger_value = ntohl (trail_setup->destination_finger); | 3174 | destination_finger_value = ntohl (trail_setup->destination_finger); |
3175 | |||
3176 | /* Trail setup request looped back to me. */ | ||
3177 | if(0 == GNUNET_CRYPTO_cmp_peer_identity (&source, &my_identity)) | ||
3178 | { | ||
3179 | finger_table_add (&my_identity, NULL, 0, finger_map_index); | ||
3180 | return GNUNET_OK; | ||
3181 | } | ||
3035 | 3182 | ||
3036 | /* My routing state size has crossed the threshold, I can not be part of any more | 3183 | #if 0 |
3037 | * trails. */ | 3184 | /* FIXME: Here we need to check 3 things |
3038 | if(GDS_ROUTING_check_threshold()) | 3185 | * 1. if my routing table is all full |
3186 | * 2. if all my friends are congested | ||
3187 | * 3. if trail threshold of my friends have crossed. | ||
3188 | * In all these cases we need to send back trail rejection message. */ | ||
3189 | if ( (GNUNET_YES == all_friends_trail_threshold) | ||
3190 | || (GNUNET_YES == GDS_ROUTING_check_threshold())) | ||
3039 | { | 3191 | { |
3040 | /* No more trails possible through me. send a trail rejection message. */ | 3192 | /* If all the friends have reached their trail threshold or if there is no |
3193 | more space in routing table to store more trails, then reject. */ | ||
3041 | GDS_NEIGHBOURS_send_trail_rejection (&source, destination_finger_value, &my_identity, | 3194 | GDS_NEIGHBOURS_send_trail_rejection (&source, destination_finger_value, &my_identity, |
3042 | peer,finger_map_index, trail_peer_list,trail_length); | 3195 | peer,finger_map_index, trail_peer_list,trail_length); |
3043 | return GNUNET_OK; | 3196 | return GNUNET_OK; |
3044 | } | 3197 | } |
3198 | #endif | ||
3045 | 3199 | ||
3046 | /* Check if you are current_destination or not. */ | 3200 | /* Check if you are current_destination or not. */ |
3047 | if (0 != (GNUNET_CRYPTO_cmp_peer_identity (¤t_destination, &my_identity))) | 3201 | if (0 != (GNUNET_CRYPTO_cmp_peer_identity (¤t_destination, &my_identity))) |
3048 | { | 3202 | { |
3049 | next_hop = GDS_ROUTING_search (¤t_source, ¤t_destination, peer); | 3203 | next_hop = GDS_ROUTING_search (¤t_source, ¤t_destination, peer); |
3050 | /* ADDNOW: OPTIMIZATION: do find_successor also and get a better path if possible. */ | 3204 | /* OPTIMIZATION: Choose a peer from find_successor and choose the closest one. |
3051 | 3205 | In case the closest one is from routing table and it is NULL, then update | |
3206 | statistics. */ | ||
3052 | if (next_hop == NULL) | 3207 | if (next_hop == NULL) |
3053 | { | 3208 | { |
3054 | /* FIXME next_hop is NULL, in a case when next_hop was a friend which got disconnected | 3209 | /* FIXME: Should we inform the peer before us. If not then it may continue |
3055 | * and we removed the trail from our routing trail. So, I can send the message | 3210 | to send us request. But in case we want to inform we need to have a |
3056 | * to other peer or can drop the message. VERIFY which will be the correct | 3211 | different kind of message. */ |
3057 | * thing to do. next_hop to NULL, 1. statistics update, drop the message. | 3212 | GNUNET_STATISTICS_update (GDS_stats, |
3058 | * 2. complain to sender with new message: trail lost */ | 3213 | gettext_noop ("# Trail not found in routing table during" |
3214 | "trail setup request, packet dropped."), | ||
3215 | 1, GNUNET_NO); | ||
3059 | return GNUNET_OK; | 3216 | return GNUNET_OK; |
3060 | } | 3217 | } |
3061 | } | 3218 | } |
3062 | else | 3219 | else |
3063 | { | 3220 | { |
3064 | next_hop = find_successor (destination_finger_value, ¤t_destination, ¤t_source, NULL); | 3221 | next_hop = find_successor (destination_finger_value, ¤t_destination, ¤t_source); |
3065 | } | 3222 | |
3066 | 3223 | if (NULL == next_hop) | |
3067 | if (0 == (GNUNET_CRYPTO_cmp_peer_identity (¤t_destination, &my_identity))) /* This means I am the final destination */ | 3224 | return GNUNET_SYSERR; |
3068 | { | 3225 | |
3069 | /* SUPU: trail length is 0, when I am the friend of the source peer. */ | 3226 | if (0 == (GNUNET_CRYPTO_cmp_peer_identity (¤t_destination, &my_identity))) /* This means I am the final destination */ |
3070 | if (trail_length == 0) | ||
3071 | { | ||
3072 | memcpy (&next_peer, &source, sizeof (struct GNUNET_PeerIdentity)); | ||
3073 | } | ||
3074 | else | ||
3075 | { | 3227 | { |
3076 | memcpy (&next_peer, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity)); | 3228 | if (trail_length == 0) |
3077 | } | 3229 | { |
3078 | 3230 | memcpy (&next_peer, &source, sizeof (struct GNUNET_PeerIdentity)); | |
3079 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer); | 3231 | } |
3080 | /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */ | 3232 | else |
3081 | compare_and_update_predecessor (&source, trail_peer_list, trail_length ); | 3233 | { |
3234 | memcpy (&next_peer, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity)); | ||
3235 | } | ||
3082 | 3236 | ||
3083 | GDS_NEIGHBOURS_send_trail_setup_result (&source, | 3237 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer); |
3084 | &(my_identity), | 3238 | |
3085 | target_friend, trail_length, | 3239 | /* ! HAVE A PREDECESSOR || (source_peer closer than existing PREDECESOR) */ |
3086 | trail_peer_list, | 3240 | if (PREDECESSOR_FINGER_ID != finger_map_index) |
3087 | finger_map_index); | 3241 | { |
3088 | return GNUNET_OK; | 3242 | /* FIXME: Is this correct assumption? A peer which think I am its predecessor, |
3243 | then I am not its predecessor. */ | ||
3244 | compare_and_update_predecessor (&source, trail_peer_list, trail_length ); | ||
3245 | } | ||
3246 | |||
3247 | GDS_NEIGHBOURS_send_trail_setup_result (&source, | ||
3248 | &(my_identity), | ||
3249 | target_friend, trail_length, | ||
3250 | trail_peer_list, | ||
3251 | finger_map_index); | ||
3252 | return GNUNET_OK; | ||
3253 | } | ||
3089 | } | 3254 | } |
3090 | else | 3255 | |
3091 | { | 3256 | /* Now add yourself to the trail. */ |
3092 | /* Now add yourself to the trail. */ | 3257 | struct GNUNET_PeerIdentity peer_list[trail_length + 1]; |
3093 | struct GNUNET_PeerIdentity peer_list[trail_length + 1]; | 3258 | if (trail_length != 0) |
3094 | memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); | 3259 | memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); |
3095 | peer_list[trail_length] = my_identity; | 3260 | peer_list[trail_length] = my_identity; |
3096 | trail_length++; | 3261 | trail_length++; |
3097 | 3262 | ||
3098 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); | 3263 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); |
3099 | GDS_NEIGHBOURS_send_trail_setup (&source, | 3264 | GDS_NEIGHBOURS_send_trail_setup (&source, |
3100 | destination_finger_value, | 3265 | destination_finger_value, |
3101 | ¤t_destination, ¤t_source, | 3266 | ¤t_destination, ¤t_source, |
3102 | target_friend, trail_length, peer_list, | 3267 | target_friend, trail_length, peer_list, |
3103 | finger_map_index); | 3268 | finger_map_index); |
3104 | return GNUNET_OK; | 3269 | return GNUNET_OK; |
3105 | } | ||
3106 | return GNUNET_SYSERR; | ||
3107 | } | 3270 | } |
3108 | 3271 | ||
3109 | 3272 | ||
@@ -3146,13 +3309,16 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p | |||
3146 | 3309 | ||
3147 | finger_map_index = htonl (trail_result->finger_map_index); | 3310 | finger_map_index = htonl (trail_result->finger_map_index); |
3148 | trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1]; | 3311 | trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1]; |
3149 | 3312 | ||
3150 | if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer), | 3313 | if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer), |
3151 | &my_identity))) | 3314 | &my_identity))) |
3152 | { | 3315 | { |
3153 | finger_table_add (&(trail_result->finger_identity), trail_peer_list, trail_length, | 3316 | /* FIXME: Is it important to check here if source and my identity is same or not. |
3154 | finger_map_index); | 3317 | we are already checking it in handle_dht_p2p_trail_setup. And if we got that |
3155 | return GNUNET_YES; | 3318 | message then we will not get it here. */ |
3319 | finger_table_add (&(trail_result->finger_identity), trail_peer_list, trail_length, | ||
3320 | finger_map_index); | ||
3321 | return GNUNET_YES; | ||
3156 | } | 3322 | } |
3157 | else | 3323 | else |
3158 | { | 3324 | { |
@@ -3192,10 +3358,6 @@ handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *p | |||
3192 | 3358 | ||
3193 | 3359 | ||
3194 | /** | 3360 | /** |
3195 | * FIXME: Use flag in the case finger peer map does not contain predcessor | ||
3196 | * then its NULL. Ideally it should never happen. Some one sent you are verify | ||
3197 | * successor and you don't have any predecessor, then ideally you should | ||
3198 | * GNUNET_break_op(0). | ||
3199 | * Get my current predecessor from the finger peer map | 3361 | * Get my current predecessor from the finger peer map |
3200 | * @return Current predecessor. | 3362 | * @return Current predecessor. |
3201 | */ | 3363 | */ |
@@ -3206,6 +3368,7 @@ get_predecessor() | |||
3206 | struct GNUNET_PeerIdentity key_ret; | 3368 | struct GNUNET_PeerIdentity key_ret; |
3207 | unsigned int finger_index; | 3369 | unsigned int finger_index; |
3208 | struct FingerInfo *my_predecessor; | 3370 | struct FingerInfo *my_predecessor; |
3371 | int flag = 0; | ||
3209 | 3372 | ||
3210 | /* Iterate over finger peer map and extract your predecessor. */ | 3373 | /* Iterate over finger peer map and extract your predecessor. */ |
3211 | finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); | 3374 | finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); |
@@ -3214,14 +3377,19 @@ get_predecessor() | |||
3214 | if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next | 3377 | if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next |
3215 | (finger_iter,&key_ret,(const void **)&my_predecessor)) | 3378 | (finger_iter,&key_ret,(const void **)&my_predecessor)) |
3216 | { | 3379 | { |
3217 | if(1 == my_predecessor->finger_map_index) | 3380 | if(PREDECESSOR_FINGER_ID == my_predecessor->finger_map_index) |
3218 | { | 3381 | { |
3382 | flag = 1; | ||
3219 | break; | 3383 | break; |
3220 | } | 3384 | } |
3221 | } | 3385 | } |
3222 | } | 3386 | } |
3223 | GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); | 3387 | GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter); |
3224 | return my_predecessor; | 3388 | |
3389 | if (0 == flag) | ||
3390 | return NULL; | ||
3391 | else | ||
3392 | return my_predecessor; | ||
3225 | } | 3393 | } |
3226 | 3394 | ||
3227 | 3395 | ||
@@ -3261,28 +3429,36 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee | |||
3261 | GNUNET_break_op (0); | 3429 | GNUNET_break_op (0); |
3262 | return GNUNET_YES; | 3430 | return GNUNET_YES; |
3263 | } | 3431 | } |
3264 | |||
3265 | trail_peer_list = (const struct GNUNET_PeerIdentity *)&vsm[1]; | 3432 | trail_peer_list = (const struct GNUNET_PeerIdentity *)&vsm[1]; |
3266 | memcpy (&source_peer, &(vsm->source_peer), sizeof(struct GNUNET_PeerIdentity)); | 3433 | memcpy (&source_peer, &(vsm->source_peer), sizeof(struct GNUNET_PeerIdentity)); |
3434 | |||
3267 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),&my_identity))) | 3435 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),&my_identity))) |
3268 | { | 3436 | { |
3269 | struct FingerInfo *my_predecessor; | 3437 | struct FingerInfo *my_predecessor; |
3270 | |||
3271 | if (trail_length == 0) | 3438 | if (trail_length == 0) |
3439 | { | ||
3440 | /* SUPU: If I am friend of source_peer, then trail_length == 0. */ | ||
3272 | memcpy (&next_hop, &source_peer, sizeof (struct GNUNET_PeerIdentity)); | 3441 | memcpy (&next_hop, &source_peer, sizeof (struct GNUNET_PeerIdentity)); |
3442 | } | ||
3273 | else | 3443 | else |
3274 | { | 3444 | { |
3275 | int current_trail_index; | 3445 | /* SUPU: Here I am the final destination successor, and trail does not contain |
3276 | current_trail_index = search_my_index (trail_peer_list, trail_length); | 3446 | destination. So, the next hop is the last element in the trail. */ |
3277 | memcpy (&next_hop, &trail_peer_list[current_trail_index-1], sizeof (struct GNUNET_PeerIdentity)); | 3447 | memcpy (&next_hop, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity)); |
3278 | } | 3448 | } |
3279 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); | 3449 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); |
3280 | 3450 | ||
3281 | my_predecessor = get_predecessor(); | 3451 | my_predecessor = get_predecessor(); |
3452 | if (NULL == my_predecessor) | ||
3453 | { | ||
3454 | GNUNET_break(0); | ||
3455 | return GNUNET_SYSERR; | ||
3456 | } | ||
3457 | |||
3282 | if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&source_peer, | 3458 | if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&source_peer, |
3283 | &(my_predecessor->finger_identity)))) | 3459 | &(my_predecessor->finger_identity)))) |
3284 | { | 3460 | { |
3285 | 3461 | /* Source peer and my predecessor, both are same. */ | |
3286 | GDS_NEIGHBOURS_send_verify_successor_result (&source_peer, | 3462 | GDS_NEIGHBOURS_send_verify_successor_result (&source_peer, |
3287 | &(my_identity), | 3463 | &(my_identity), |
3288 | &(my_predecessor->finger_identity), | 3464 | &(my_predecessor->finger_identity), |
@@ -3299,19 +3475,24 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee | |||
3299 | 3475 | ||
3300 | new_trail_length = trail_length + my_predecessor->first_trail_length + 1; | 3476 | new_trail_length = trail_length + my_predecessor->first_trail_length + 1; |
3301 | new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * new_trail_length); | 3477 | new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * new_trail_length); |
3302 | memcpy (new_successor_trail, trail_peer_list, (trail_length) * sizeof (struct GNUNET_PeerIdentity)); | 3478 | if (trail_length > 0) |
3479 | memcpy (new_successor_trail, trail_peer_list, (trail_length) * sizeof (struct GNUNET_PeerIdentity)); | ||
3480 | |||
3303 | memcpy (&new_successor_trail[trail_length], &my_identity, sizeof (struct GNUNET_PeerIdentity)); | 3481 | memcpy (&new_successor_trail[trail_length], &my_identity, sizeof (struct GNUNET_PeerIdentity)); |
3304 | 3482 | ||
3305 | iterator = GNUNET_malloc (sizeof (struct TrailPeerList)); | 3483 | if (my_predecessor->first_trail_length) |
3306 | iterator = my_predecessor->first_trail_head; | ||
3307 | i = trail_length + 1; | ||
3308 | while (i < new_trail_length) | ||
3309 | { | 3484 | { |
3310 | memcpy (&new_successor_trail[i], &(iterator->peer), sizeof (struct GNUNET_PeerIdentity)); | 3485 | iterator = GNUNET_malloc (sizeof (struct TrailPeerList)); |
3311 | iterator = iterator->next; | 3486 | iterator = my_predecessor->first_trail_head; |
3312 | i++; | 3487 | i = trail_length + 1; |
3488 | while (i < new_trail_length) | ||
3489 | { | ||
3490 | memcpy (&new_successor_trail[i], &(iterator->peer), sizeof (struct GNUNET_PeerIdentity)); | ||
3491 | iterator = iterator->next; | ||
3492 | i++; | ||
3493 | } | ||
3313 | } | 3494 | } |
3314 | 3495 | ||
3315 | GDS_NEIGHBOURS_send_verify_successor_result (&source_peer, | 3496 | GDS_NEIGHBOURS_send_verify_successor_result (&source_peer, |
3316 | &(my_identity), | 3497 | &(my_identity), |
3317 | &(my_predecessor->finger_identity), | 3498 | &(my_predecessor->finger_identity), |
@@ -3324,12 +3505,22 @@ handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *pee | |||
3324 | else | 3505 | else |
3325 | { | 3506 | { |
3326 | int my_index; | 3507 | int my_index; |
3327 | /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/ | 3508 | |
3328 | /* FIXME: make sure you are passing the correct trail length */ | ||
3329 | my_index = search_my_index (trail_peer_list, trail_length); | 3509 | my_index = search_my_index (trail_peer_list, trail_length); |
3330 | memcpy (&next_hop, &trail_peer_list[my_index + 1], sizeof (struct GNUNET_PeerIdentity)); | 3510 | if (my_index == GNUNET_SYSERR) |
3331 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); | 3511 | { |
3332 | 3512 | GNUNET_break (0); | |
3513 | return GNUNET_SYSERR; | ||
3514 | } | ||
3515 | if (my_index == (trail_length - 1)) | ||
3516 | { | ||
3517 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(vsm->successor)); | ||
3518 | } | ||
3519 | else | ||
3520 | { | ||
3521 | memcpy (&next_hop, &trail_peer_list[my_index + 1], sizeof (struct GNUNET_PeerIdentity)); | ||
3522 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); | ||
3523 | } | ||
3333 | GDS_NEIGHBOURS_send_verify_successor (&(vsm->source_peer), &(vsm->successor),target_friend, | 3524 | GDS_NEIGHBOURS_send_verify_successor (&(vsm->source_peer), &(vsm->successor),target_friend, |
3334 | trail_peer_list, trail_length); | 3525 | trail_peer_list, trail_length); |
3335 | } | 3526 | } |
@@ -3361,7 +3552,6 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti | |||
3361 | GNUNET_break_op (0); | 3552 | GNUNET_break_op (0); |
3362 | return GNUNET_YES; | 3553 | return GNUNET_YES; |
3363 | } | 3554 | } |
3364 | |||
3365 | vsrm = (const struct PeerVerifySuccessorResultMessage *) message; | 3555 | vsrm = (const struct PeerVerifySuccessorResultMessage *) message; |
3366 | trail_length = ntohl (vsrm->trail_length); | 3556 | trail_length = ntohl (vsrm->trail_length); |
3367 | 3557 | ||
@@ -3374,6 +3564,7 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti | |||
3374 | GNUNET_break_op (0); | 3564 | GNUNET_break_op (0); |
3375 | return GNUNET_YES; | 3565 | return GNUNET_YES; |
3376 | } | 3566 | } |
3567 | /* FIXME: URGENT: What happens when trail length = 0. */ | ||
3377 | 3568 | ||
3378 | trail_peer_list = (struct GNUNET_PeerIdentity *) &vsrm[1]; | 3569 | trail_peer_list = (struct GNUNET_PeerIdentity *) &vsrm[1]; |
3379 | 3570 | ||
@@ -3381,25 +3572,51 @@ handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdenti | |||
3381 | { | 3572 | { |
3382 | if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->my_predecessor), &(my_identity)))) | 3573 | if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->my_predecessor), &(my_identity)))) |
3383 | { | 3574 | { |
3384 | finger_table_add (&(vsrm->my_predecessor), trail_peer_list, trail_length, 0); | 3575 | /* FIXME: Here we have got a new successor. But it may happen that our logic |
3385 | memcpy (&next_hop, &trail_peer_list[0], sizeof (struct GNUNET_PeerIdentity)); | 3576 | * says that this is not correct successor. so in finger table add it |
3386 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); | 3577 | * failed to update the successor and we are still sending a notify |
3387 | GDS_NEIGHBOURS_send_notify_new_successor (&my_identity, &(vsrm->my_predecessor), | 3578 | * new successor. Here trail_length will be atleast 1, in case we have a new |
3388 | target_friend, trail_peer_list, | 3579 | * successor because in that case our old successor is part of trail. |
3389 | trail_length); | 3580 | * Could it be possible that our identity and my_predecessor is same. Check it. */ |
3390 | return GNUNET_OK; | 3581 | if (GNUNET_YES == finger_table_add (&(vsrm->my_predecessor), trail_peer_list, trail_length, 0)) |
3582 | { | ||
3583 | memcpy (&next_hop, &trail_peer_list[0], sizeof (struct GNUNET_PeerIdentity)); | ||
3584 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); | ||
3585 | GDS_NEIGHBOURS_send_notify_new_successor (&my_identity, &(vsrm->my_predecessor), | ||
3586 | target_friend, trail_peer_list, | ||
3587 | trail_length); | ||
3588 | return GNUNET_OK; | ||
3589 | } | ||
3590 | /*else | ||
3591 | { | ||
3592 | |||
3593 | GNUNET_break (0); | ||
3594 | return GNUNET_SYSERR; | ||
3595 | }*/ | ||
3391 | } | 3596 | } |
3392 | } | 3597 | } |
3393 | else | 3598 | else |
3394 | { | 3599 | { |
3395 | int my_index; | 3600 | int my_index; |
3396 | /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/ | 3601 | |
3397 | /* FIXME: make sure you are passing the correct trail length */ | ||
3398 | my_index = search_my_index (trail_peer_list, trail_length); | 3602 | my_index = search_my_index (trail_peer_list, trail_length); |
3399 | if (my_index == 1) | 3603 | if (GNUNET_SYSERR == my_index) |
3604 | { | ||
3605 | GNUNET_break (0); | ||
3606 | return GNUNET_SYSERR; | ||
3607 | } | ||
3608 | |||
3609 | if (my_index == 0) | ||
3610 | { | ||
3611 | /* Source is not part of trail, so if I am the last one then my index | ||
3612 | should be 0. */ | ||
3400 | memcpy (&next_hop, &(vsrm->destination_peer), sizeof (struct GNUNET_PeerIdentity)); | 3613 | memcpy (&next_hop, &(vsrm->destination_peer), sizeof (struct GNUNET_PeerIdentity)); |
3614 | } | ||
3401 | else | 3615 | else |
3616 | { | ||
3402 | memcpy (&next_hop, &trail_peer_list[my_index-1], sizeof (struct GNUNET_PeerIdentity)); | 3617 | memcpy (&next_hop, &trail_peer_list[my_index-1], sizeof (struct GNUNET_PeerIdentity)); |
3618 | } | ||
3619 | |||
3403 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); | 3620 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); |
3404 | GDS_NEIGHBOURS_send_verify_successor_result (&(vsrm->destination_peer), | 3621 | GDS_NEIGHBOURS_send_verify_successor_result (&(vsrm->destination_peer), |
3405 | &(vsrm->source_successor), | 3622 | &(vsrm->source_successor), |
@@ -3435,7 +3652,6 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity | |||
3435 | GNUNET_break_op (0); | 3652 | GNUNET_break_op (0); |
3436 | return GNUNET_YES; | 3653 | return GNUNET_YES; |
3437 | } | 3654 | } |
3438 | |||
3439 | nsm = (const struct PeerNotifyNewSuccessorMessage *) message; | 3655 | nsm = (const struct PeerNotifyNewSuccessorMessage *) message; |
3440 | trail_length = ntohl (nsm->trail_length); | 3656 | trail_length = ntohl (nsm->trail_length); |
3441 | 3657 | ||
@@ -3452,8 +3668,18 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity | |||
3452 | 3668 | ||
3453 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer), &my_identity))) | 3669 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer), &my_identity))) |
3454 | { | 3670 | { |
3455 | //update_predecessor (&(nsm->destination_peer), trail_peer_list); | 3671 | /* I am the new successor. */ |
3456 | return GNUNET_OK; | 3672 | struct GNUNET_PeerIdentity new_predecessor; |
3673 | memcpy (&new_predecessor, &(nsm->source_peer), sizeof (struct GNUNET_PeerIdentity)); | ||
3674 | if (GNUNET_NO == compare_and_update_predecessor (&new_predecessor, trail_peer_list, | ||
3675 | trail_length)) | ||
3676 | { | ||
3677 | /* Someone claims to be my predecessor but its not closest predecessor | ||
3678 | the break. */ | ||
3679 | GNUNET_break (0); | ||
3680 | return GNUNET_SYSERR; | ||
3681 | } | ||
3682 | return GNUNET_OK; | ||
3457 | } | 3683 | } |
3458 | else | 3684 | else |
3459 | { | 3685 | { |
@@ -3461,11 +3687,22 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity | |||
3461 | struct GNUNET_PeerIdentity next_hop; | 3687 | struct GNUNET_PeerIdentity next_hop; |
3462 | int my_index; | 3688 | int my_index; |
3463 | 3689 | ||
3464 | /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/ | ||
3465 | /* FIXME: check that trail length is correct. */ | ||
3466 | my_index = search_my_index (trail_peer_list, trail_length); | 3690 | my_index = search_my_index (trail_peer_list, trail_length); |
3467 | memcpy (&next_hop, &trail_peer_list[my_index+1], sizeof (struct GNUNET_PeerIdentity)); | 3691 | if (GNUNET_SYSERR == my_index) |
3468 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); | 3692 | { |
3693 | GNUNET_break(0); | ||
3694 | return GNUNET_SYSERR; | ||
3695 | } | ||
3696 | |||
3697 | if (my_index == (trail_length - 1)) | ||
3698 | { | ||
3699 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(nsm->destination_peer)); | ||
3700 | } | ||
3701 | else | ||
3702 | { | ||
3703 | memcpy (&next_hop, &trail_peer_list[my_index+1], sizeof (struct GNUNET_PeerIdentity)); | ||
3704 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); | ||
3705 | } | ||
3469 | GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer), | 3706 | GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer), |
3470 | &(nsm->destination_peer), | 3707 | &(nsm->destination_peer), |
3471 | target_friend, trail_peer_list, | 3708 | target_friend, trail_peer_list, |
@@ -3477,6 +3714,12 @@ handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity | |||
3477 | 3714 | ||
3478 | 3715 | ||
3479 | /** | 3716 | /** |
3717 | * FIXME; Should we call select_random_friend from here in case I am the source | ||
3718 | * of the message or should I just return and in next iteration by default | ||
3719 | * we will call select random friend from send_find_finger_trail. But in that | ||
3720 | * case we should maintain a list of congested peer which failed to setup the | ||
3721 | * trail. and then in select random friend we should ignore them. this list | ||
3722 | * should have an expiration time and we should garbage collect it periodically. | ||
3480 | * Core handler for P2P trail rejection message | 3723 | * Core handler for P2P trail rejection message |
3481 | * @param cls closure | 3724 | * @param cls closure |
3482 | * @param message message | 3725 | * @param message message |
@@ -3532,44 +3775,26 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity * | |||
3532 | GNUNET_break_op (0); | 3775 | GNUNET_break_op (0); |
3533 | return GNUNET_YES; | 3776 | return GNUNET_YES; |
3534 | } | 3777 | } |
3778 | |||
3535 | trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1]; | 3779 | trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1]; |
3536 | finger_map_index = ntohl (trail_rejection->finger_map_index); | 3780 | finger_map_index = ntohl (trail_rejection->finger_map_index); |
3537 | memcpy (&source_peer, &(trail_rejection->source_peer), sizeof(struct GNUNET_PeerIdentity)); | 3781 | memcpy (&source_peer, &(trail_rejection->source_peer), sizeof(struct GNUNET_PeerIdentity)); |
3538 | memcpy (&destination_finger_value, &(trail_rejection->finger_identity_value), sizeof (uint64_t)); | 3782 | memcpy (&destination_finger_value, &(trail_rejection->finger_identity_value), sizeof (uint64_t)); |
3539 | memcpy (&congested_peer, &(trail_rejection->congested_peer), sizeof (struct GNUNET_PeerIdentity)); | 3783 | memcpy (&congested_peer, &(trail_rejection->congested_peer), sizeof (struct GNUNET_PeerIdentity)); |
3540 | 3784 | ||
3541 | /* If I am the source of the original trail setup message, then again select | ||
3542 | a random friend and send a new trail setup message to this finger identity | ||
3543 | value. */ | ||
3544 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &source_peer))) | 3785 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &source_peer))) |
3545 | { | 3786 | { |
3546 | /* If friend peer map is empty, or all the friends trail threshold has been crossed, | 3787 | /* I am the source of original trail setup message. Do nothing and exit. */ |
3547 | * then return. */ | 3788 | /* In current implementation, when we don't get the result of a trail setup, |
3548 | if ((GNUNET_CONTAINER_multipeermap_size (friend_peermap) == 0) || | 3789 | then no entry is added to finger table and hence, by default a trail setup for |
3549 | (all_friends_trail_threshold == GNUNET_YES)) | 3790 | the same finger map index is sent. so we don't need to send it here. */ |
3550 | { | ||
3551 | GNUNET_break(0); | ||
3552 | return GNUNET_SYSERR; | ||
3553 | } | ||
3554 | |||
3555 | /* Select any random friend except congested peer. */ | ||
3556 | target_friend = select_random_friend (&congested_peer); | ||
3557 | |||
3558 | if (NULL == target_friend) | ||
3559 | { | ||
3560 | all_friends_trail_threshold = GNUNET_YES; | ||
3561 | return GNUNET_SYSERR; | ||
3562 | } | ||
3563 | |||
3564 | GDS_NEIGHBOURS_send_trail_setup (&my_identity, destination_finger_value, &(target_friend->id), | ||
3565 | &my_identity, target_friend, 0, NULL, finger_map_index); | ||
3566 | return GNUNET_YES; | 3791 | return GNUNET_YES; |
3567 | } | 3792 | } |
3568 | 3793 | ||
3569 | /* My routing state size has crossed the threshold, I can not be part of any more | ||
3570 | * trails. */ | ||
3571 | if(GDS_ROUTING_check_threshold()) | 3794 | if(GDS_ROUTING_check_threshold()) |
3572 | { | 3795 | { |
3796 | /* My routing state size has crossed the threshold, I can not be part of any more | ||
3797 | * trails. */ | ||
3573 | struct GNUNET_PeerIdentity *new_trail; | 3798 | struct GNUNET_PeerIdentity *new_trail; |
3574 | 3799 | ||
3575 | if (trail_length == 1) | 3800 | if (trail_length == 1) |
@@ -3578,6 +3803,8 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity * | |||
3578 | } | 3803 | } |
3579 | else | 3804 | else |
3580 | { | 3805 | { |
3806 | /* FIXME: Here if I got the trail rejection message then I am the last element | ||
3807 | in the trail. So, I should choose trail_length-2.*/ | ||
3581 | memcpy (&next_peer, &trail_peer_list[trail_length - 2], sizeof (struct GNUNET_PeerIdentity)); | 3808 | memcpy (&next_peer, &trail_peer_list[trail_length - 2], sizeof (struct GNUNET_PeerIdentity)); |
3582 | } | 3809 | } |
3583 | 3810 | ||
@@ -3591,21 +3818,14 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity * | |||
3591 | return GNUNET_YES; | 3818 | return GNUNET_YES; |
3592 | } | 3819 | } |
3593 | 3820 | ||
3594 | /* FIXME: In this case I have just written my_identity as current_destination | ||
3595 | and current source need ot think more of better values anad if needed or not. | ||
3596 | Also, i am adding a new parameter to funciton find_successor so that this peer | ||
3597 | is not considered as next hop congested_peer is not being used. FIXME. */ | ||
3598 | memcpy (¤t_destination, &my_identity, sizeof (struct GNUNET_PeerIdentity)); | 3821 | memcpy (¤t_destination, &my_identity, sizeof (struct GNUNET_PeerIdentity)); |
3599 | memcpy (¤t_source, &my_identity, sizeof (struct GNUNET_PeerIdentity)); | 3822 | memcpy (¤t_source, &my_identity, sizeof (struct GNUNET_PeerIdentity)); |
3600 | next_hop = find_successor (destination_finger_value, ¤t_destination, ¤t_source, &congested_peer); | 3823 | /* FIXME: After adding a new field in struct FriendInfo congested, then call |
3824 | find successor then it will never consider that friend by default. */ | ||
3825 | next_hop = find_successor (destination_finger_value, ¤t_destination, ¤t_source); | ||
3601 | 3826 | ||
3602 | /* FIXME: WE NEED ANOTHER CASE as it may happend that congested peer is the only | 3827 | if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, ¤t_destination))) /* This means I am the final destination */ |
3603 | friend, and find_successor finds nothig, so check something else | ||
3604 | here like if current_destination is me, it means that i am destination | ||
3605 | or if current_destination = NULL, then it means found nothing. URGENT. */ | ||
3606 | if (NULL == next_hop) /* This means I am the final destination */ | ||
3607 | { | 3828 | { |
3608 | /* SUPU: trail length is 1, when I am the friend of the srouce peer. */ | ||
3609 | if (trail_length == 1) | 3829 | if (trail_length == 1) |
3610 | { | 3830 | { |
3611 | memcpy (&next_peer, &source_peer, sizeof (struct GNUNET_PeerIdentity)); | 3831 | memcpy (&next_peer, &source_peer, sizeof (struct GNUNET_PeerIdentity)); |
@@ -3625,6 +3845,30 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity * | |||
3625 | finger_map_index); | 3845 | finger_map_index); |
3626 | return GNUNET_OK; | 3846 | return GNUNET_OK; |
3627 | } | 3847 | } |
3848 | else if (NULL == next_hop) | ||
3849 | { | ||
3850 | /* No peer found. Send a trail rejection message to previous peer in the trail. */ | ||
3851 | |||
3852 | struct GNUNET_PeerIdentity *new_trail; | ||
3853 | |||
3854 | if (trail_length == 1) | ||
3855 | { | ||
3856 | memcpy (&next_peer, &source_peer, sizeof (struct GNUNET_PeerIdentity)); | ||
3857 | } | ||
3858 | else | ||
3859 | { | ||
3860 | memcpy (&next_peer, &trail_peer_list[trail_length - 2], sizeof (struct GNUNET_PeerIdentity)); | ||
3861 | } | ||
3862 | |||
3863 | /* Remove myself from the trail. */ | ||
3864 | new_trail = GNUNET_malloc ((trail_length -1) * sizeof (struct GNUNET_PeerIdentity)); | ||
3865 | memcpy (new_trail, trail_peer_list, (trail_length -1) * sizeof (struct GNUNET_PeerIdentity)); | ||
3866 | |||
3867 | /* No more trails possible through me. send a trail rejection message to next hop. */ | ||
3868 | GDS_NEIGHBOURS_send_trail_rejection (&source_peer, destination_finger_value, &my_identity, | ||
3869 | &next_peer,finger_map_index, new_trail,trail_length - 1); | ||
3870 | return GNUNET_YES; | ||
3871 | } | ||
3628 | else | 3872 | else |
3629 | { | 3873 | { |
3630 | /* Now add yourself to the trail. */ | 3874 | /* Now add yourself to the trail. */ |
@@ -3646,6 +3890,10 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity * | |||
3646 | 3890 | ||
3647 | 3891 | ||
3648 | /** | 3892 | /** |
3893 | * FIXME: we don't send trail teardown to finger for which the trail was setup. | ||
3894 | * Trail teardown only aim is to remove entries from the routing table. Destination | ||
3895 | * finger does not have any entry in its routing table. So, it does not need | ||
3896 | * a trail teardown. | ||
3649 | * Core handle for p2p trail tear down messages. | 3897 | * Core handle for p2p trail tear down messages. |
3650 | * @param cls closure | 3898 | * @param cls closure |
3651 | * @param message message | 3899 | * @param message message |
@@ -3653,13 +3901,9 @@ int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity * | |||
3653 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | 3901 | * @return GNUNET_OK on success, GNUNET_SYSERR on error |
3654 | */ | 3902 | */ |
3655 | static | 3903 | static |
3656 | int handle_dht_p2p_trail_treadown (void *cls, const struct GNUNET_PeerIdentity *peer, | 3904 | int handle_dht_p2p_trail_teardown (void *cls, const struct GNUNET_PeerIdentity *peer, |
3657 | const struct GNUNET_MessageHeader *message) | 3905 | const struct GNUNET_MessageHeader *message) |
3658 | { | 3906 | { |
3659 | /* Call is made to this function when the source peer removes an existing | ||
3660 | finger entry and it need to inform the peers which are part of the trail to remove | ||
3661 | the trail from their routing table. So, this peer should first | ||
3662 | get the next hop and then delete the entry. */ | ||
3663 | struct PeerTrailTearDownMessage *trail_teardown; | 3907 | struct PeerTrailTearDownMessage *trail_teardown; |
3664 | struct GNUNET_PeerIdentity *trail_peer_list; | 3908 | struct GNUNET_PeerIdentity *trail_peer_list; |
3665 | struct GNUNET_PeerIdentity next_hop; | 3909 | struct GNUNET_PeerIdentity next_hop; |
@@ -3691,14 +3935,17 @@ int handle_dht_p2p_trail_treadown (void *cls, const struct GNUNET_PeerIdentity * | |||
3691 | 3935 | ||
3692 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_teardown->destination_peer), &my_identity))) | 3936 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_teardown->destination_peer), &my_identity))) |
3693 | { | 3937 | { |
3694 | /* We have reached destination then just return. May be if the peer before this | 3938 | /* I am the destination of the trail, but I am not part of trail. I don't |
3695 | destination, does not forward the packet to destination. So, this case should never | 3939 | need to remove any entry from my routing table. So, I should not get this |
3696 | occur. */ | 3940 | message. */ |
3697 | GNUNET_break (0); | 3941 | GNUNET_break (0); |
3698 | return GNUNET_YES; | 3942 | return GNUNET_YES; |
3699 | } | 3943 | } |
3700 | 3944 | ||
3701 | my_index = search_my_index (trail_peer_list, trail_length); | 3945 | my_index = search_my_index (trail_peer_list, trail_length); |
3946 | if(GNUNET_SYSERR == my_index) | ||
3947 | return GNUNET_SYSERR; | ||
3948 | |||
3702 | if (GNUNET_NO == GDS_ROUTING_remove_trail (&(trail_teardown->source_peer), | 3949 | if (GNUNET_NO == GDS_ROUTING_remove_trail (&(trail_teardown->source_peer), |
3703 | &(trail_teardown->destination_peer),peer)) | 3950 | &(trail_teardown->destination_peer),peer)) |
3704 | { | 3951 | { |
@@ -3708,8 +3955,9 @@ int handle_dht_p2p_trail_treadown (void *cls, const struct GNUNET_PeerIdentity * | |||
3708 | return GNUNET_YES; | 3955 | return GNUNET_YES; |
3709 | } | 3956 | } |
3710 | 3957 | ||
3711 | if (my_index == (trail_length - 2)) | 3958 | /* I am the last element of the trail. */ |
3712 | return GNUNET_SYSERR; | 3959 | if(my_index == trail_length - 1) |
3960 | return GNUNET_YES; | ||
3713 | 3961 | ||
3714 | memcpy (&next_hop, &trail_peer_list[my_index + 1], sizeof (struct GNUNET_PeerIdentity)); | 3962 | memcpy (&next_hop, &trail_peer_list[my_index + 1], sizeof (struct GNUNET_PeerIdentity)); |
3715 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); | 3963 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); |
@@ -3738,7 +3986,8 @@ remove_matching_finger (void *cls, | |||
3738 | struct FingerInfo *remove_finger = value; | 3986 | struct FingerInfo *remove_finger = value; |
3739 | const struct GNUNET_PeerIdentity *disconnected_peer = cls; | 3987 | const struct GNUNET_PeerIdentity *disconnected_peer = cls; |
3740 | 3988 | ||
3741 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_finger->first_trail_head->peer, disconnected_peer)) | 3989 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_finger->first_trail_head->peer, disconnected_peer) |
3990 | || (0 == GNUNET_CRYPTO_cmp_peer_identity (&(remove_finger->finger_identity), disconnected_peer))) | ||
3742 | { | 3991 | { |
3743 | GNUNET_assert (GNUNET_YES == | 3992 | GNUNET_assert (GNUNET_YES == |
3744 | GNUNET_CONTAINER_multipeermap_remove (finger_peermap, | 3993 | GNUNET_CONTAINER_multipeermap_remove (finger_peermap, |
@@ -3746,6 +3995,7 @@ remove_matching_finger (void *cls, | |||
3746 | remove_finger)); | 3995 | remove_finger)); |
3747 | free_finger (remove_finger); | 3996 | free_finger (remove_finger); |
3748 | } | 3997 | } |
3998 | |||
3749 | return GNUNET_YES; | 3999 | return GNUNET_YES; |
3750 | } | 4000 | } |
3751 | 4001 | ||
@@ -3775,12 +4025,16 @@ handle_core_disconnect (void *cls, | |||
3775 | GNUNET_break (0); | 4025 | GNUNET_break (0); |
3776 | return; | 4026 | return; |
3777 | } | 4027 | } |
3778 | 4028 | ||
3779 | /* Remove fingers for which this peer is the first element in the trail. */ | 4029 | /* Remove fingers for which this peer is the first element in the trail or if |
4030 | * the friend is a finger. */ | ||
3780 | GNUNET_CONTAINER_multipeermap_iterate (finger_peermap, | 4031 | GNUNET_CONTAINER_multipeermap_iterate (finger_peermap, |
3781 | &remove_matching_finger, (void *)peer); | 4032 | &remove_matching_finger, (void *)peer); |
3782 | 4033 | ||
3783 | /* Remove routing trails of which this peer is a part. */ | 4034 | /* Remove routing trails of which this peer is a part. |
4035 | * FIXME: Here do we only remove the entry from our own routing table | ||
4036 | * or do we also inform other peers which are part of trail. It seems to be | ||
4037 | * too much of messages exchanged. */ | ||
3784 | GDS_ROUTING_remove_entry (peer); | 4038 | GDS_ROUTING_remove_entry (peer); |
3785 | 4039 | ||
3786 | /* Remove the peer from friend_peermap. */ | 4040 | /* Remove the peer from friend_peermap. */ |
@@ -3861,6 +4115,9 @@ core_init (void *cls, | |||
3861 | const struct GNUNET_PeerIdentity *identity) | 4115 | const struct GNUNET_PeerIdentity *identity) |
3862 | { | 4116 | { |
3863 | my_identity = *identity; | 4117 | my_identity = *identity; |
4118 | |||
4119 | FPRINTF (stderr,_("\nSUPU %s, %s, %d, my_identity = %s"), | ||
4120 | __FILE__, __func__,__LINE__, GNUNET_i2s(&my_identity)); | ||
3864 | } | 4121 | } |
3865 | 4122 | ||
3866 | 4123 | ||
@@ -3881,7 +4138,7 @@ GDS_NEIGHBOURS_init (void) | |||
3881 | {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0}, | 4138 | {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0}, |
3882 | {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0}, | 4139 | {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0}, |
3883 | {&handle_dht_p2p_trail_rejection, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION, 0}, | 4140 | {&handle_dht_p2p_trail_rejection, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION, 0}, |
3884 | {&handle_dht_p2p_trail_treadown, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN, 0}, | 4141 | {&handle_dht_p2p_trail_teardown, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN, 0}, |
3885 | {NULL, 0, 0} | 4142 | {NULL, 0, 0} |
3886 | }; | 4143 | }; |
3887 | 4144 | ||
@@ -3894,9 +4151,8 @@ GDS_NEIGHBOURS_init (void) | |||
3894 | 4151 | ||
3895 | friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO); | 4152 | friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO); |
3896 | finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS * 4/3, GNUNET_NO); | 4153 | finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS * 4/3, GNUNET_NO); |
3897 | |||
3898 | all_friends_trail_threshold = GNUNET_NO; | 4154 | all_friends_trail_threshold = GNUNET_NO; |
3899 | 4155 | ||
3900 | return GNUNET_OK; | 4156 | return GNUNET_OK; |
3901 | } | 4157 | } |
3902 | 4158 | ||
@@ -3923,7 +4179,10 @@ GDS_NEIGHBOURS_done (void) | |||
3923 | 4179 | ||
3924 | /* FIXME: Here I have added GNUNET_break(0) as ideally if friend_peermap | 4180 | /* FIXME: Here I have added GNUNET_break(0) as ideally if friend_peermap |
3925 | is already zero, then we really don't need to cancel it again. If this | 4181 | is already zero, then we really don't need to cancel it again. If this |
3926 | condition happens it mean we might have missed some corner case. */ | 4182 | condition happens it mean we might have missed some corner case. But we |
4183 | cancel the task only in handle_core_disconnect. it may happen that this | ||
4184 | function is called but not handle_core_disconnect, In that case GNUNET_break(0) | ||
4185 | is not needed. */ | ||
3927 | if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task) | 4186 | if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task) |
3928 | { | 4187 | { |
3929 | GNUNET_break (0); | 4188 | GNUNET_break (0); |
@@ -3941,6 +4200,7 @@ GDS_NEIGHBOURS_done (void) | |||
3941 | 4200 | ||
3942 | 4201 | ||
3943 | /** | 4202 | /** |
4203 | * URGENT | ||
3944 | * FIXME: Here I want to send only the value not the address. Initially | 4204 | * FIXME: Here I want to send only the value not the address. Initially |
3945 | * I wanted to make it const struct * so that no other function can change it. | 4205 | * I wanted to make it const struct * so that no other function can change it. |
3946 | * then in client file, i make a copy and send that copy. now I have made this | 4206 | * then in client file, i make a copy and send that copy. now I have made this |
diff --git a/src/dht/gnunet-service-xdht_routing.c b/src/dht/gnunet-service-xdht_routing.c index ac27370a9..3601a4186 100644 --- a/src/dht/gnunet-service-xdht_routing.c +++ b/src/dht/gnunet-service-xdht_routing.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2011 Christian Grothoff (and other contributing authors) | 3 | (C) 2011 - 2014 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -226,14 +226,15 @@ GDS_ROUTING_search(struct GNUNET_PeerIdentity *source_peer, | |||
226 | 226 | ||
227 | 227 | ||
228 | /** | 228 | /** |
229 | * FIXME:URGENT:Better name. | ||
229 | * Check if the size of routing table has crossed threshold. | 230 | * Check if the size of routing table has crossed threshold. |
230 | * @return | 231 | * @return #GNUNET_YES, if threshold crossed else #GNUNET_NO. |
231 | */ | 232 | */ |
232 | int | 233 | int |
233 | GDS_ROUTING_check_threshold () | 234 | GDS_ROUTING_check_threshold () |
234 | { | 235 | { |
235 | int ret; | 236 | int ret; |
236 | ret = (GNUNET_CONTAINER_multipeermap_size(routing_table) > ROUTING_TABLE_THRESHOLD) ? 1:0; | 237 | ret = (GNUNET_CONTAINER_multipeermap_size(routing_table) > ROUTING_TABLE_THRESHOLD) ? GNUNET_YES:GNUNET_NO; |
237 | return ret; | 238 | return ret; |
238 | } | 239 | } |
239 | 240 | ||
diff --git a/src/dht/gnunet-service-xdht_routing.h b/src/dht/gnunet-service-xdht_routing.h index efda58a94..63007c7e4 100644 --- a/src/dht/gnunet-service-xdht_routing.h +++ b/src/dht/gnunet-service-xdht_routing.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2011 Christian Grothoff (and other contributing authors) | 3 | (C) 2011 - 2014 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |