aboutsummaryrefslogtreecommitdiff
path: root/src/dv
diff options
context:
space:
mode:
Diffstat (limited to 'src/dv')
-rw-r--r--src/dv/dv_api.c22
-rw-r--r--src/dv/gnunet-service-dv.c117
-rw-r--r--src/dv/plugin_transport_dv.c9
3 files changed, 123 insertions, 25 deletions
diff --git a/src/dv/dv_api.c b/src/dv/dv_api.c
index 9e99790fb..ace020c3e 100644
--- a/src/dv/dv_api.c
+++ b/src/dv/dv_api.c
@@ -151,6 +151,7 @@ transmit_pending (void *cls, size_t size, void *buf)
151{ 151{
152 struct GNUNET_DV_Handle *handle = cls; 152 struct GNUNET_DV_Handle *handle = cls;
153 size_t ret; 153 size_t ret;
154 size_t tsize;
154 155
155 if (buf == NULL) 156 if (buf == NULL)
156 { 157 {
@@ -159,6 +160,21 @@ transmit_pending (void *cls, size_t size, void *buf)
159 } 160 }
160 handle->th = NULL; 161 handle->th = NULL;
161 162
163 ret = 0;
164
165 if (handle->current != NULL)
166 {
167 tsize = ntohs(handle->current->msg->header.size);
168 if (size >= tsize)
169 {
170 memcpy(buf, handle->current->msg, tsize);
171 }
172 else
173 {
174 return ret;
175 }
176 }
177
162 return ret; 178 return ret;
163} 179}
164 180
@@ -255,6 +271,11 @@ void handle_message_receipt (void *cls,
255 char *sender_address; 271 char *sender_address;
256 char *packed_msg; 272 char *packed_msg;
257 273
274 if (msg == NULL)
275 {
276 return; /* Connection closed? */
277 }
278
258 GNUNET_assert(ntohs(msg->type) == GNUNET_MESSAGE_TYPE_TRANSPORT_DV_RECEIVE); 279 GNUNET_assert(ntohs(msg->type) == GNUNET_MESSAGE_TYPE_TRANSPORT_DV_RECEIVE);
259 280
260 if (ntohs(msg->size) < sizeof(struct GNUNET_DV_MessageReceived)) 281 if (ntohs(msg->size) < sizeof(struct GNUNET_DV_MessageReceived))
@@ -323,7 +344,6 @@ int GNUNET_DV_send (struct GNUNET_DV_Handle *dv_handle,
323 memcpy(&msg[1], addr, addrlen); 344 memcpy(&msg[1], addr, addrlen);
324 345
325 add_pending(dv_handle, msg); 346 add_pending(dv_handle, msg);
326 process_pending_message(dv_handle);
327 347
328 return GNUNET_OK; 348 return GNUNET_OK;
329} 349}
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,
diff --git a/src/dv/plugin_transport_dv.c b/src/dv/plugin_transport_dv.c
index 7d0b1521f..fa35fa5a8 100644
--- a/src/dv/plugin_transport_dv.c
+++ b/src/dv/plugin_transport_dv.c
@@ -166,19 +166,20 @@ struct Plugin
166 166
167}; 167};
168 168
169
170void handle_dv_message_received (void *cls, 169void handle_dv_message_received (void *cls,
171 struct GNUNET_PeerIdentity *sender, 170 struct GNUNET_PeerIdentity *sender,
172 struct GNUNET_MessageHeader *msg, 171 char *msg,
172 size_t msg_len,
173 unsigned int distance, 173 unsigned int distance,
174 char *sender_address, 174 char *sender_address,
175 size_t sender_address_len) 175 size_t sender_address_len)
176{ 176{
177 struct Plugin *plugin = cls; 177 struct Plugin *plugin = cls;
178 178
179 /* TODO: Add in demultiplexing if we think we'll be receiving multiple messages at once */
179 plugin->env->receive(plugin, 180 plugin->env->receive(plugin,
180 sender, 181 sender,
181 msg, 182 (struct GNUNET_MessageHeader *)msg,
182 distance, 183 distance,
183 sender_address, 184 sender_address,
184 sender_address_len); 185 sender_address_len);
@@ -336,7 +337,7 @@ libgnunet_plugin_transport_dv_init (void *cls)
336 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; 337 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
337 struct GNUNET_TRANSPORT_PluginFunctions *api; 338 struct GNUNET_TRANSPORT_PluginFunctions *api;
338 struct Plugin *plugin; 339 struct Plugin *plugin;
339 struct GNUNET_SERVICE_Context *service; 340 /*struct GNUNET_SERVICE_Context *service;*/
340 341
341 /** 342 /**
342 * Do we not even need a service for this thing? That's peculiar. 343 * Do we not even need a service for this thing? That's peculiar.