aboutsummaryrefslogtreecommitdiff
path: root/src/dv/gnunet-service-dv.c
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2010-03-14 17:02:29 +0000
committerNathan S. Evans <evans@in.tum.de>2010-03-14 17:02:29 +0000
commit3e812a14846665f56f4d5e94a7285c02810581b0 (patch)
tree7ed1ca8eb7f2d1311261e5a33d67b6c22213b7ea /src/dv/gnunet-service-dv.c
parent5fabaa6b5f27ea2b8289f3a1b15cfce270d81368 (diff)
downloadgnunet-3e812a14846665f56f4d5e94a7285c02810581b0.tar.gz
gnunet-3e812a14846665f56f4d5e94a7285c02810581b0.zip
fondly remembering ciphertext_send... all the pieces are there, but still doesn't work. Needs debugging, as usual.
Diffstat (limited to 'src/dv/gnunet-service-dv.c')
-rw-r--r--src/dv/gnunet-service-dv.c117
1 files changed, 97 insertions, 20 deletions
diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c
index 0e182fca8..683fe46b9 100644
--- a/src/dv/gnunet-service-dv.c
+++ b/src/dv/gnunet-service-dv.c
@@ -51,7 +51,7 @@ static struct GNUNET_CORE_Handle *coreAPI;
51/** 51/**
52 * The identity of our peer. 52 * The identity of our peer.
53 */ 53 */
54const struct GNUNET_PeerIdentity *my_identity; 54struct GNUNET_PeerIdentity my_identity;
55 55
56/** 56/**
57 * The configuration for this service. 57 * The configuration for this service.
@@ -155,6 +155,30 @@ struct PendingMessage
155 155
156 156
157/** 157/**
158 * Context created whenever a direct peer connects to us,
159 * used to gossip other peers to it.
160 */
161struct NeighborSendContext
162{
163 /**
164 * The peer we will gossip to.
165 */
166 struct DirectNeighbor *toNeighbor;
167
168 /**
169 * The timeout for this task.
170 */
171 struct GNUNET_TIME_Relative timeout;
172
173 /**
174 * The task associated with this context.
175 */
176 GNUNET_SCHEDULER_TaskIdentifier task;
177
178};
179
180
181/**
158 * Struct to hold information for updating existing neighbors 182 * Struct to hold information for updating existing neighbors
159 */ 183 */
160struct NeighborUpdateInfo 184struct NeighborUpdateInfo
@@ -203,6 +227,11 @@ struct DirectNeighbor
203 struct DistantNeighbor *referee_tail; 227 struct DistantNeighbor *referee_tail;
204 228
205 /** 229 /**
230 * The sending context for gossiping peers to this neighbor.
231 */
232 struct NeighborSendContext *send_context;
233
234 /**
206 * Is this one of the direct neighbors that we are "hiding" 235 * Is this one of the direct neighbors that we are "hiding"
207 * from DV? 236 * from DV?
208 */ 237 */
@@ -312,8 +341,6 @@ struct GNUNET_DV_Context
312 341
313 unsigned long long max_table_size; 342 unsigned long long max_table_size;
314 343
315 struct GNUNET_TIME_Relative send_interval;
316
317 unsigned int neighbor_id_loc; 344 unsigned int neighbor_id_loc;
318 345
319 int closing; 346 int closing;
@@ -470,7 +497,7 @@ send_message (const struct GNUNET_PeerIdentity * recipient,
470 &sender->hashPubKey); 497 &sender->hashPubKey);
471 if (source == NULL) 498 if (source == NULL)
472 { 499 {
473 if (0 != (memcmp (my_identity, 500 if (0 != (memcmp (&my_identity,
474 sender, sizeof (struct GNUNET_PeerIdentity)))) 501 sender, sizeof (struct GNUNET_PeerIdentity))))
475 { 502 {
476 /* sender unknown to us, drop! */ 503 /* sender unknown to us, drop! */
@@ -634,10 +661,11 @@ static void
634neighbor_send_task (void *cls, 661neighbor_send_task (void *cls,
635 const struct GNUNET_SCHEDULER_TaskContext *tc) 662 const struct GNUNET_SCHEDULER_TaskContext *tc)
636{ 663{
664 struct NeighborSendContext *send_context = cls;
637#if DEBUG_DV 665#if DEBUG_DV
638 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 666 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
639 "%s: Entering neighbor_send_thread...\n", 667 "%s: Entering neighbor_send_task...\n",
640 GNUNET_i2s(my_identity)); 668 GNUNET_i2s(&my_identity));
641 char * encPeerAbout; 669 char * encPeerAbout;
642 char * encPeerTo; 670 char * encPeerTo;
643#endif 671#endif
@@ -648,10 +676,30 @@ neighbor_send_task (void *cls,
648 struct PendingMessage *pending_message; 676 struct PendingMessage *pending_message;
649 677
650 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) 678 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
679 {
680#if DEBUG_DV
681 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
682 "%s: Called with reason shutdown, shutting down!\n",
683 GNUNET_i2s(&my_identity));
684#endif
685 send_context->toNeighbor->send_context = NULL;
686 GNUNET_free(send_context);
651 return; 687 return;
688 }
689
652 690
691 /* FIXME: this may become a problem, because the heap walk has only one internal "walker". This means
692 * that if two neighbor_send_tasks are operating in lockstep (which is quite possible, given default
693 * values for all connected peers) there may be a serious bias as to which peers get gossiped about!
694 * Probably the *best* way to fix would be to have an opaque pointer to the walk position passed as
695 * part of the walk_get_next call. Then the heap would have to keep a list of walks, or reset the walk
696 * whenever a modification has been detected. Yuck either way. Perhaps we could iterate over the heap
697 * once to get a list of peers to gossip about and gossip them over time... But then if one goes away
698 * in the mean time that becomes nasty. For now we'll just assume that the walking is done
699 * asynchronously enough to avoid major problems (-;
700 */
653 about = GNUNET_CONTAINER_heap_walk_get_next (ctx.neighbor_min_heap); 701 about = GNUNET_CONTAINER_heap_walk_get_next (ctx.neighbor_min_heap);
654 to = GNUNET_CONTAINER_heap_get_random (ctx.neighbor_min_heap, GNUNET_CONTAINER_multihashmap_size(ctx.direct_neighbors)); 702 to = send_context->toNeighbor;
655 703
656 if ((about != NULL) && (to != about->referrer /* split horizon */ ) && 704 if ((about != NULL) && (to != about->referrer /* split horizon */ ) &&
657#if SUPPORT_HIDING 705#if SUPPORT_HIDING
@@ -666,7 +714,7 @@ neighbor_send_task (void *cls,
666 encPeerTo = GNUNET_strdup(GNUNET_i2s(&to->identity)); 714 encPeerTo = GNUNET_strdup(GNUNET_i2s(&to->identity));
667 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 715 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
668 "%s: Sending info about peer %s to directly connected peer %s\n", 716 "%s: Sending info about peer %s to directly connected peer %s\n",
669 GNUNET_i2s(my_identity), 717 GNUNET_i2s(&my_identity),
670 encPeerAbout, encPeerTo); 718 encPeerAbout, encPeerTo);
671#endif 719#endif
672 pending_message = GNUNET_malloc(sizeof(struct PendingMessage)); 720 pending_message = GNUNET_malloc(sizeof(struct PendingMessage));
@@ -692,7 +740,7 @@ neighbor_send_task (void *cls,
692 ctx.send_interval);*/ 740 ctx.send_interval);*/
693 } 741 }
694 742
695 gossip_task = GNUNET_SCHEDULER_add_delayed(sched, ctx.send_interval, &neighbor_send_task, NULL); 743 GNUNET_SCHEDULER_add_delayed(sched, send_context->timeout, &neighbor_send_task, send_context);
696 return; 744 return;
697} 745}
698 746
@@ -816,7 +864,7 @@ void core_init (void *cls,
816 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 864 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
817 "%s: Core connection initialized, I am peer: %s\n", "dv", GNUNET_i2s(identity)); 865 "%s: Core connection initialized, I am peer: %s\n", "dv", GNUNET_i2s(identity));
818#endif 866#endif
819 my_identity = identity; 867 memcpy(&my_identity, identity, sizeof(struct GNUNET_PeerIdentity));
820 coreAPI = server; 868 coreAPI = server;
821} 869}
822 870
@@ -985,7 +1033,7 @@ addUpdateNeighbor (const struct GNUNET_PeerIdentity * peer,
985 1033
986 1034
987/** 1035/**
988 * Method called whenever a given peer either connects. 1036 * Method called whenever a peer connects.
989 * 1037 *
990 * @param cls closure 1038 * @param cls closure
991 * @param peer peer identity this notification is about 1039 * @param peer peer identity this notification is about
@@ -1003,12 +1051,27 @@ void handle_core_connect (void *cls,
1003 "%s: Receives core connect message for peer %s distance %d!\n", "dv", GNUNET_i2s(peer), distance); 1051 "%s: Receives core connect message for peer %s distance %d!\n", "dv", GNUNET_i2s(peer), distance);
1004#endif 1052#endif
1005 1053
1006 neighbor = GNUNET_malloc (sizeof (struct DirectNeighbor)); 1054 if ((distance == 0) && (GNUNET_CONTAINER_multihashmap_get(ctx.direct_neighbors, &peer->hashPubKey) == NULL))
1007 memcpy (&neighbor->identity, peer, sizeof (struct GNUNET_PeerIdentity)); 1055 {
1008 GNUNET_CONTAINER_multihashmap_put (ctx.direct_neighbors, 1056 neighbor = GNUNET_malloc (sizeof (struct DirectNeighbor));
1009 &peer->hashPubKey, 1057 neighbor->send_context = GNUNET_malloc(sizeof(struct NeighborSendContext));
1010 neighbor, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); 1058 neighbor->send_context->toNeighbor = neighbor;
1011 addUpdateNeighbor (peer, 0, neighbor, 0); 1059 neighbor->send_context->timeout = default_dv_delay; /* FIXME: base this on total gossip tasks, or bandwidth */
1060 memcpy (&neighbor->identity, peer, sizeof (struct GNUNET_PeerIdentity));
1061 GNUNET_CONTAINER_multihashmap_put (ctx.direct_neighbors,
1062 &peer->hashPubKey,
1063 neighbor, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1064 addUpdateNeighbor (peer, 0, neighbor, 0);
1065 neighbor->send_context->task = GNUNET_SCHEDULER_add_now(sched, &neighbor_send_task, neighbor->send_context);
1066 }
1067 else
1068 {
1069#if DEBUG_DV
1070 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1071 "%s: Distance (%d) greater than 0 or already know about peer (%s), not re-adding!\n", "dv", distance, GNUNET_i2s(peer));
1072#endif
1073 return;
1074 }
1012} 1075}
1013 1076
1014/** 1077/**
@@ -1039,6 +1102,8 @@ void handle_core_disconnect (void *cls,
1039 GNUNET_assert (neighbor->referee_tail == NULL); 1102 GNUNET_assert (neighbor->referee_tail == NULL);
1040 GNUNET_CONTAINER_multihashmap_remove (ctx.direct_neighbors, 1103 GNUNET_CONTAINER_multihashmap_remove (ctx.direct_neighbors,
1041 &peer->hashPubKey, neighbor); 1104 &peer->hashPubKey, neighbor);
1105 if ((neighbor->send_context != NULL) && (neighbor->send_context->task != GNUNET_SCHEDULER_NO_TASK))
1106 GNUNET_SCHEDULER_cancel(sched, neighbor->send_context->task);
1042 GNUNET_free (neighbor); 1107 GNUNET_free (neighbor);
1043} 1108}
1044 1109
@@ -1058,11 +1123,25 @@ run (void *cls,
1058 const struct GNUNET_CONFIGURATION_Handle *c) 1123 const struct GNUNET_CONFIGURATION_Handle *c)
1059{ 1124{
1060 struct GNUNET_TIME_Relative timeout; 1125 struct GNUNET_TIME_Relative timeout;
1061 1126 unsigned long long max_hosts;
1062 timeout = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5); 1127 timeout = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5);
1063 sched = scheduler; 1128 sched = scheduler;
1064 cfg = c; 1129 cfg = c;
1065 1130
1131 /* FIXME: Read from config, or calculate, or something other than this! */
1132 max_hosts = 50;
1133 ctx.max_table_size = 100;
1134 ctx.fisheye_depth = 3;
1135
1136 ctx.neighbor_min_heap =
1137 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1138 ctx.neighbor_max_heap =
1139 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MAX);
1140
1141 ctx.direct_neighbors = GNUNET_CONTAINER_multihashmap_create (max_hosts);
1142 ctx.extended_neighbors =
1143 GNUNET_CONTAINER_multihashmap_create (ctx.max_table_size * 3);
1144
1066 client_transmit_timeout = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5); 1145 client_transmit_timeout = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5);
1067 default_dv_delay = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5); 1146 default_dv_delay = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5);
1068 GNUNET_SERVER_add_handlers (server, plugin_handlers); 1147 GNUNET_SERVER_add_handlers (server, plugin_handlers);
@@ -1086,8 +1165,6 @@ run (void *cls,
1086 /* load (server); Huh? */ 1165 /* load (server); Huh? */
1087 1166
1088 /* Scheduled the task to clean up when shutdown is called */ 1167 /* Scheduled the task to clean up when shutdown is called */
1089
1090 gossip_task = GNUNET_SCHEDULER_add_delayed(sched, ctx.send_interval, &neighbor_send_task, NULL);
1091 cleanup_task = GNUNET_SCHEDULER_add_delayed (sched, 1168 cleanup_task = GNUNET_SCHEDULER_add_delayed (sched,
1092 GNUNET_TIME_UNIT_FOREVER_REL, 1169 GNUNET_TIME_UNIT_FOREVER_REL,
1093 &shutdown_task, 1170 &shutdown_task,