diff options
author | Nathan S. Evans <evans@in.tum.de> | 2010-03-14 17:02:29 +0000 |
---|---|---|
committer | Nathan S. Evans <evans@in.tum.de> | 2010-03-14 17:02:29 +0000 |
commit | 3e812a14846665f56f4d5e94a7285c02810581b0 (patch) | |
tree | 7ed1ca8eb7f2d1311261e5a33d67b6c22213b7ea /src/dv/gnunet-service-dv.c | |
parent | 5fabaa6b5f27ea2b8289f3a1b15cfce270d81368 (diff) | |
download | gnunet-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.c | 117 |
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 | */ |
54 | const struct GNUNET_PeerIdentity *my_identity; | 54 | struct 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 | */ | ||
161 | struct 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 | */ |
160 | struct NeighborUpdateInfo | 184 | struct 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 | |||
634 | neighbor_send_task (void *cls, | 661 | neighbor_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, |