diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-03-14 09:32:55 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-03-14 09:32:55 +0000 |
commit | 0fc66b10df8428e8f9539479d08e8c69a891da56 (patch) | |
tree | 5cd1a5b8bc481f23cef497e96447fe4a4c9b29d3 /src/dv | |
parent | 25543ab8fed7935d490bb396ac376a1ca0c74b7b (diff) | |
download | gnunet-0fc66b10df8428e8f9539479d08e8c69a891da56.tar.gz gnunet-0fc66b10df8428e8f9539479d08e8c69a891da56.zip |
-more DV hacking
Diffstat (limited to 'src/dv')
-rw-r--r-- | src/dv/gnunet-service-dv.c | 196 |
1 files changed, 130 insertions, 66 deletions
diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c index 6cf828a3b..b1cf51dd9 100644 --- a/src/dv/gnunet-service-dv.c +++ b/src/dv/gnunet-service-dv.c | |||
@@ -26,7 +26,6 @@ | |||
26 | * | 26 | * |
27 | * @author Christian Grothoff | 27 | * @author Christian Grothoff |
28 | * @author Nathan Evans | 28 | * @author Nathan Evans |
29 | * | ||
30 | */ | 29 | */ |
31 | #include "platform.h" | 30 | #include "platform.h" |
32 | #include "gnunet_util_lib.h" | 31 | #include "gnunet_util_lib.h" |
@@ -54,6 +53,7 @@ | |||
54 | */ | 53 | */ |
55 | #define DIRECT_NEIGHBOR_COST 1 | 54 | #define DIRECT_NEIGHBOR_COST 1 |
56 | 55 | ||
56 | |||
57 | GNUNET_NETWORK_STRUCT_BEGIN | 57 | GNUNET_NETWORK_STRUCT_BEGIN |
58 | 58 | ||
59 | /** | 59 | /** |
@@ -169,6 +169,8 @@ struct DirectNeighbor | |||
169 | /** | 169 | /** |
170 | * Routing table of the neighbor, NULL if not yet established. | 170 | * Routing table of the neighbor, NULL if not yet established. |
171 | * Keys are peer identities, values are 'struct Target' entries. | 171 | * Keys are peer identities, values are 'struct Target' entries. |
172 | * Note that the distances in the targets are from the point-of-view | ||
173 | * of the peer, not from us! | ||
172 | */ | 174 | */ |
173 | struct GNUNET_CONTAINER_MultiHashMap *neighbor_table; | 175 | struct GNUNET_CONTAINER_MultiHashMap *neighbor_table; |
174 | 176 | ||
@@ -176,6 +178,8 @@ struct DirectNeighbor | |||
176 | * Updated routing table of the neighbor, under construction, | 178 | * Updated routing table of the neighbor, under construction, |
177 | * NULL if we are not currently building it. | 179 | * NULL if we are not currently building it. |
178 | * Keys are peer identities, values are 'struct Target' entries. | 180 | * Keys are peer identities, values are 'struct Target' entries. |
181 | * Note that the distances in the targets are from the point-of-view | ||
182 | * of the peer, not from us! | ||
179 | */ | 183 | */ |
180 | struct GNUNET_CONTAINER_MultiHashMap *neighbor_table_consensus; | 184 | struct GNUNET_CONTAINER_MultiHashMap *neighbor_table_consensus; |
181 | 185 | ||
@@ -256,7 +260,8 @@ static struct GNUNET_CONTAINER_MultiHashMap *direct_neighbors; | |||
256 | 260 | ||
257 | /** | 261 | /** |
258 | * Hashmap with all routes that we currently support; contains | 262 | * Hashmap with all routes that we currently support; contains |
259 | * routing information for all peers up to distance DEFAULT_FISHEYE_DEPTH. | 263 | * routing information for all peers from distance 2 |
264 | * up to distance DEFAULT_FISHEYE_DEPTH. | ||
260 | */ | 265 | */ |
261 | static struct GNUNET_CONTAINER_MultiHashMap *all_routes; | 266 | static struct GNUNET_CONTAINER_MultiHashMap *all_routes; |
262 | 267 | ||
@@ -623,6 +628,58 @@ get_consensus_slot (uint32_t distance) | |||
623 | 628 | ||
624 | 629 | ||
625 | /** | 630 | /** |
631 | * Allocate a slot in the consensus set for a route. | ||
632 | * | ||
633 | * @param route route to initialize | ||
634 | * @param distance which consensus set to use | ||
635 | */ | ||
636 | static void | ||
637 | allocate_route (struct Route *route, | ||
638 | uint32_t distance) | ||
639 | { | ||
640 | unsigned int i; | ||
641 | |||
642 | i = get_consensus_slot (distance); | ||
643 | route->set_offset = i; | ||
644 | consensi[distance].targets[i] = route; | ||
645 | route->target.distance = distance; | ||
646 | } | ||
647 | |||
648 | |||
649 | /** | ||
650 | * Release a slot in the consensus set for a route. | ||
651 | * | ||
652 | * @param route route to release the slot from | ||
653 | */ | ||
654 | static void | ||
655 | release_route (struct Route *route) | ||
656 | { | ||
657 | consensi[route->target.distance].targets[route->set_offset] = NULL; | ||
658 | route->set_offset = UINT_MAX; /* indicate invalid slot */ | ||
659 | } | ||
660 | |||
661 | |||
662 | /** | ||
663 | * Move a route from one consensus set to another. | ||
664 | * | ||
665 | * @param route route to move | ||
666 | * @param new_distance new distance for the route (destination set) | ||
667 | */ | ||
668 | static void | ||
669 | move_route (struct Route *route, | ||
670 | uint32_t new_distance) | ||
671 | { | ||
672 | unsigned int i; | ||
673 | |||
674 | release_route (route); | ||
675 | i = get_consensus_slot (new_distance); | ||
676 | route->set_offset = i; | ||
677 | consensi[new_distance].targets[i] = route; | ||
678 | route->target.distance = new_distance; | ||
679 | } | ||
680 | |||
681 | |||
682 | /** | ||
626 | * Method called whenever a peer connects. | 683 | * Method called whenever a peer connects. |
627 | * | 684 | * |
628 | * @param cls closure | 685 | * @param cls closure |
@@ -638,7 +695,6 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
638 | struct DirectNeighbor *neighbor; | 695 | struct DirectNeighbor *neighbor; |
639 | struct Route *route; | 696 | struct Route *route; |
640 | uint32_t distance; | 697 | uint32_t distance; |
641 | unsigned int i; | ||
642 | 698 | ||
643 | /* Check for connect to self message */ | 699 | /* Check for connect to self message */ |
644 | if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) | 700 | if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) |
@@ -660,32 +716,15 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
660 | &peer->hashPubKey, | 716 | &peer->hashPubKey, |
661 | neighbor, | 717 | neighbor, |
662 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 718 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
663 | |||
664 | route = GNUNET_CONTAINER_multihashmap_get (all_routes, | 719 | route = GNUNET_CONTAINER_multihashmap_get (all_routes, |
665 | &peer->hashPubKey); | 720 | &peer->hashPubKey); |
666 | if (NULL == route) | 721 | if (NULL != route) |
667 | { | ||
668 | route->target.peer = *peer; | ||
669 | i = get_consensus_slot (DIRECT_NEIGHBOR_COST); | ||
670 | route->set_offset = i; | ||
671 | consensi[DIRECT_NEIGHBOR_COST].targets[i] = route; | ||
672 | GNUNET_assert (GNUNET_YES == | ||
673 | GNUNET_CONTAINER_multihashmap_put (all_routes, | ||
674 | &route->target.peer.hashPubKey, | ||
675 | route, | ||
676 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
677 | } | ||
678 | else | ||
679 | { | 722 | { |
680 | /* move to new consensi slot */ | ||
681 | send_disconnect_to_plugin (peer); | 723 | send_disconnect_to_plugin (peer); |
682 | consensi[route->target.distance].targets[route->set_offset] = NULL; | 724 | release_route (route); |
683 | i = get_consensus_slot (DIRECT_NEIGHBOR_COST); | 725 | GNUNET_free (route); |
684 | route->set_offset = i; | ||
685 | consensi[DIRECT_NEIGHBOR_COST].targets[i] = route; | ||
686 | } | 726 | } |
687 | route->next_hop = neighbor; | 727 | route->next_hop = neighbor; |
688 | route->target.distance = DIRECT_NEIGHBOR_COST; | ||
689 | // FIXME: begin exchange_routing_information! | 728 | // FIXME: begin exchange_routing_information! |
690 | } | 729 | } |
691 | 730 | ||
@@ -749,10 +788,11 @@ cull_routes (void *cls, const struct GNUNET_HashCode * key, void *value) | |||
749 | 788 | ||
750 | if (route->next_hop != neighbor) | 789 | if (route->next_hop != neighbor) |
751 | return GNUNET_YES; /* not affected */ | 790 | return GNUNET_YES; /* not affected */ |
752 | 791 | GNUNET_assert (GNUNET_YES == | |
753 | /* FIXME: destroy route! */ | 792 | GNUNET_CONTAINER_multihashmap_remove (all_routes, key, value)); |
754 | GNUNET_break (0); | 793 | release_route (route); |
755 | 794 | send_disconnect_to_plugin (&route->target.peer); | |
795 | GNUNET_free (route); | ||
756 | return GNUNET_YES; | 796 | return GNUNET_YES; |
757 | } | 797 | } |
758 | 798 | ||
@@ -763,35 +803,41 @@ cull_routes (void *cls, const struct GNUNET_HashCode * key, void *value) | |||
763 | * | 803 | * |
764 | * @param cls the direct neighbor for the given route | 804 | * @param cls the direct neighbor for the given route |
765 | * @param key key value stored under | 805 | * @param key key value stored under |
766 | * @param value a 'struct Target' that may or may not be useful | 806 | * @param value a 'struct Target' that may or may not be useful; not that |
767 | * | 807 | * the distance in 'target' does not include the first hop yet |
768 | * @return GNUNET_YES to continue iteration, GNUNET_NO to stop | 808 | * @return GNUNET_YES to continue iteration, GNUNET_NO to stop |
769 | */ | 809 | */ |
770 | static int | 810 | static int |
771 | cull_routes (void *cls, const struct GNUNET_HashCode * key, void *value) | 811 | check_possible_route (void *cls, const struct GNUNET_HashCode * key, void *value) |
772 | { | 812 | { |
773 | struct DirectNeighbor *neighbor = cls; | 813 | struct DirectNeighbor *neighbor = cls; |
774 | struct Target *target = value; | 814 | struct Target *target = value; |
775 | struct Route *cur; | 815 | struct Route *route; |
776 | 816 | ||
777 | cur = GNUNET_CONTAINER_multihashmap_get (all_routes, | 817 | route = GNUNET_CONTAINER_multihashmap_get (all_routes, |
778 | key); | 818 | key); |
779 | if (NULL != cur) | 819 | if (NULL != route) |
780 | { | 820 | { |
781 | if (cur->target.distance > target->distance) | 821 | if (route->target.distance > target->distance + 1) |
782 | { | 822 | { |
783 | /* FIXME: this 'target' is cheaper than the existing route; | 823 | /* this 'target' is cheaper than the existing route; switch to alternative route! */ |
784 | switch route! */ | 824 | move_route (route, target->distance + 1); |
825 | route->next_hop = neighbor; | ||
826 | // FIXME: notify plugin about distance update? | ||
785 | } | 827 | } |
786 | return GNUNET_YES; /* got a route to this target already */ | 828 | return GNUNET_YES; /* got a route to this target already */ |
787 | } | 829 | } |
788 | cur = GNUNET_malloc (sizeof (struct Route)); | 830 | route = GNUNET_malloc (sizeof (struct Route)); |
789 | cur->next_hop = neighbor; | 831 | route->next_hop = neighbor; |
790 | cur->target = *target; | 832 | route->target.distance = target->distance + 1; |
791 | cur->set_offset = get_consensus_slot (target->distance); | 833 | route->target.peer = target->peer; |
792 | GNUNET_CONTAINER_multihashmap_put (all_routes, | 834 | allocate_route (route, route->target.distance); |
793 | key, | 835 | GNUNET_assert (GNUNET_YES == |
794 | cur); | 836 | GNUNET_CONTAINER_multihashmap_put (all_routes, |
837 | &route->target.peer.hashPubKey, | ||
838 | route, | ||
839 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
840 | send_connect_to_plugin (&route->target.peer, target->distance); | ||
795 | return GNUNET_YES; | 841 | return GNUNET_YES; |
796 | } | 842 | } |
797 | 843 | ||
@@ -819,30 +865,15 @@ refresh_routes (void *cls, const struct GNUNET_HashCode * key, void *value) | |||
819 | 865 | ||
820 | 866 | ||
821 | /** | 867 | /** |
822 | * Method called whenever a given peer disconnects. | 868 | * Cleanup all of the data structures associated with a given neighbor. |
823 | * | 869 | * |
824 | * @param cls closure | 870 | * @param neighbor neighbor to clean up |
825 | * @param peer peer identity this notification is about | ||
826 | */ | 871 | */ |
827 | static void | 872 | static void |
828 | handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) | 873 | cleanup_neighbor (struct DirectNeighbor *neighbor) |
829 | { | 874 | { |
830 | struct DirectNeighbor *neighbor; | ||
831 | struct PendingMessage *pending; | 875 | struct PendingMessage *pending; |
832 | 876 | ||
833 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
834 | "Received core peer disconnect message for peer `%s'!\n", | ||
835 | GNUNET_i2s (peer)); | ||
836 | /* Check for disconnect from self message */ | ||
837 | if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) | ||
838 | return; | ||
839 | neighbor = | ||
840 | GNUNET_CONTAINER_multihashmap_get (direct_neighbors, &peer->hashPubKey); | ||
841 | if (NULL == neighbor) | ||
842 | { | ||
843 | /* must have been a DV-neighbor, ignore */ | ||
844 | return; | ||
845 | } | ||
846 | while (NULL != (pending = neighbor->pm_head)) | 877 | while (NULL != (pending = neighbor->pm_head)) |
847 | { | 878 | { |
848 | GNUNET_CONTAINER_DLL_remove (neighbor->pm_head, | 879 | GNUNET_CONTAINER_DLL_remove (neighbor->pm_head, |
@@ -860,16 +891,43 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) | |||
860 | } | 891 | } |
861 | GNUNET_assert (GNUNET_YES == | 892 | GNUNET_assert (GNUNET_YES == |
862 | GNUNET_CONTAINER_multihashmap_remove (direct_neighbors, | 893 | GNUNET_CONTAINER_multihashmap_remove (direct_neighbors, |
863 | &peer->hashPubKey, | 894 | &neighbor->peer.hashPubKey, |
864 | neighbor)); | 895 | neighbor)); |
865 | GNUNET_free (neighbor); | 896 | GNUNET_free (neighbor); |
897 | } | ||
898 | |||
899 | |||
900 | /** | ||
901 | * Method called whenever a given peer disconnects. | ||
902 | * | ||
903 | * @param cls closure | ||
904 | * @param peer peer identity this notification is about | ||
905 | */ | ||
906 | static void | ||
907 | handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) | ||
908 | { | ||
909 | struct DirectNeighbor *neighbor; | ||
910 | |||
911 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
912 | "Received core peer disconnect message for peer `%s'!\n", | ||
913 | GNUNET_i2s (peer)); | ||
914 | /* Check for disconnect from self message */ | ||
915 | if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) | ||
916 | return; | ||
917 | neighbor = | ||
918 | GNUNET_CONTAINER_multihashmap_get (direct_neighbors, &peer->hashPubKey); | ||
919 | if (NULL == neighbor) | ||
920 | { | ||
921 | /* must have been a DV-neighbor, ignore */ | ||
922 | return; | ||
923 | } | ||
924 | cleanup_neighbor (neighbor); | ||
866 | GNUNET_CONTAINER_multihashmap_iterate (direct_neighbors, | 925 | GNUNET_CONTAINER_multihashmap_iterate (direct_neighbors, |
867 | &refresh_routes, | 926 | &refresh_routes, |
868 | NULL); | 927 | NULL); |
869 | } | 928 | } |
870 | 929 | ||
871 | 930 | ||
872 | |||
873 | /** | 931 | /** |
874 | * Multihashmap iterator for freeing routes. Should never be called. | 932 | * Multihashmap iterator for freeing routes. Should never be called. |
875 | * | 933 | * |
@@ -882,8 +940,14 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) | |||
882 | static int | 940 | static int |
883 | free_route (void *cls, const struct GNUNET_HashCode * key, void *value) | 941 | free_route (void *cls, const struct GNUNET_HashCode * key, void *value) |
884 | { | 942 | { |
943 | struct Route *route = value; | ||
944 | |||
885 | GNUNET_break (0); | 945 | GNUNET_break (0); |
886 | // FIXME: notify client about disconnect | 946 | GNUNET_assert (GNUNET_YES == |
947 | GNUNET_CONTAINER_multihashmap_remove (all_routes, key, value)); | ||
948 | release_route (route); | ||
949 | send_disconnect_to_plugin (&route->target.peer); | ||
950 | GNUNET_free (route); | ||
887 | return GNUNET_YES; | 951 | return GNUNET_YES; |
888 | } | 952 | } |
889 | 953 | ||
@@ -900,10 +964,10 @@ free_route (void *cls, const struct GNUNET_HashCode * key, void *value) | |||
900 | static int | 964 | static int |
901 | free_direct_neighbors (void *cls, const struct GNUNET_HashCode * key, void *value) | 965 | free_direct_neighbors (void *cls, const struct GNUNET_HashCode * key, void *value) |
902 | { | 966 | { |
903 | struct DirectNeighbor *dn = value; | 967 | struct DirectNeighbor *neighbor = value; |
904 | 968 | ||
905 | GNUNET_break (0); | 969 | GNUNET_break (0); |
906 | // FIXME: release resources, ... | 970 | cleanup_neighbor (neighbor); |
907 | return GNUNET_YES; | 971 | return GNUNET_YES; |
908 | } | 972 | } |
909 | 973 | ||