aboutsummaryrefslogtreecommitdiff
path: root/src/dv
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-03-14 09:32:55 +0000
committerChristian Grothoff <christian@grothoff.org>2013-03-14 09:32:55 +0000
commit0fc66b10df8428e8f9539479d08e8c69a891da56 (patch)
tree5cd1a5b8bc481f23cef497e96447fe4a4c9b29d3 /src/dv
parent25543ab8fed7935d490bb396ac376a1ca0c74b7b (diff)
downloadgnunet-0fc66b10df8428e8f9539479d08e8c69a891da56.tar.gz
gnunet-0fc66b10df8428e8f9539479d08e8c69a891da56.zip
-more DV hacking
Diffstat (limited to 'src/dv')
-rw-r--r--src/dv/gnunet-service-dv.c196
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
57GNUNET_NETWORK_STRUCT_BEGIN 57GNUNET_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 */
261static struct GNUNET_CONTAINER_MultiHashMap *all_routes; 266static 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 */
636static void
637allocate_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 */
654static void
655release_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 */
668static void
669move_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 */
770static int 810static int
771cull_routes (void *cls, const struct GNUNET_HashCode * key, void *value) 811check_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 */
827static void 872static void
828handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) 873cleanup_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 */
906static void
907handle_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)
882static int 940static int
883free_route (void *cls, const struct GNUNET_HashCode * key, void *value) 941free_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)
900static int 964static int
901free_direct_neighbors (void *cls, const struct GNUNET_HashCode * key, void *value) 965free_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