diff options
-rw-r--r-- | src/cadet/gnunet-service-cadet-new.h | 12 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet-new_dht.h | 4 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet-new_paths.c | 110 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet-new_paths.h | 6 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet-new_peer.c | 64 |
5 files changed, 172 insertions, 24 deletions
diff --git a/src/cadet/gnunet-service-cadet-new.h b/src/cadet/gnunet-service-cadet-new.h index 694a5f7fd..2b68862b7 100644 --- a/src/cadet/gnunet-service-cadet-new.h +++ b/src/cadet/gnunet-service-cadet-new.h | |||
@@ -28,6 +28,8 @@ | |||
28 | #ifndef GNUNET_SERVICE_CADET_H | 28 | #ifndef GNUNET_SERVICE_CADET_H |
29 | #define GNUNET_SERVICE_CADET_H | 29 | #define GNUNET_SERVICE_CADET_H |
30 | 30 | ||
31 | #include "gnunet_util_lib.h" | ||
32 | |||
31 | /** | 33 | /** |
32 | * A client to the CADET service. | 34 | * A client to the CADET service. |
33 | */ | 35 | */ |
@@ -77,6 +79,16 @@ struct CadetPeerPathEntry | |||
77 | * Path this entry belongs to. | 79 | * Path this entry belongs to. |
78 | */ | 80 | */ |
79 | struct CadetPeerPath *path; | 81 | struct CadetPeerPath *path; |
82 | |||
83 | /** | ||
84 | * Path's historic score up to this point. Basically, how often did | ||
85 | * we succeed or fail to use the path up to this entry in a | ||
86 | * connection. Positive values indicate good experiences, negative | ||
87 | * values bad experiences. Code updating the score must guard | ||
88 | * against overflows. | ||
89 | */ | ||
90 | int score; | ||
91 | |||
80 | }; | 92 | }; |
81 | 93 | ||
82 | 94 | ||
diff --git a/src/cadet/gnunet-service-cadet-new_dht.h b/src/cadet/gnunet-service-cadet-new_dht.h index 70f834de5..ff3923790 100644 --- a/src/cadet/gnunet-service-cadet-new_dht.h +++ b/src/cadet/gnunet-service-cadet-new_dht.h | |||
@@ -51,11 +51,11 @@ struct GCD_search_handle; | |||
51 | * | 51 | * |
52 | * @param cls Closure. | 52 | * @param cls Closure. |
53 | * @param path An unchecked, unoptimized path to the target node. | 53 | * @param path An unchecked, unoptimized path to the target node. |
54 | * After callback will no longer be valid! | 54 | * After callback will no longer be valid, unless #GCPP_acquire() is called! |
55 | */ | 55 | */ |
56 | typedef void | 56 | typedef void |
57 | (*GCD_search_callback) (void *cls, | 57 | (*GCD_search_callback) (void *cls, |
58 | const struct CadetPeerPath *path); | 58 | struct CadetPeerPath *path); |
59 | 59 | ||
60 | 60 | ||
61 | /** | 61 | /** |
diff --git a/src/cadet/gnunet-service-cadet-new_paths.c b/src/cadet/gnunet-service-cadet-new_paths.c index baffb20d2..663ce317f 100644 --- a/src/cadet/gnunet-service-cadet-new_paths.c +++ b/src/cadet/gnunet-service-cadet-new_paths.c | |||
@@ -26,9 +26,49 @@ | |||
26 | * @author Christian Grothoff | 26 | * @author Christian Grothoff |
27 | */ | 27 | */ |
28 | #include "platform.h" | 28 | #include "platform.h" |
29 | #include "gnunet-service-cadet-new_peer.h" | ||
29 | #include "gnunet-service-cadet-new_paths.h" | 30 | #include "gnunet-service-cadet-new_paths.h" |
30 | 31 | ||
31 | 32 | ||
33 | /** | ||
34 | * Information regarding a possible path to reach a peer. | ||
35 | */ | ||
36 | struct CadetPeerPath | ||
37 | { | ||
38 | |||
39 | /** | ||
40 | * Array of all the peers on the path. If @e hn is non-NULL, the | ||
41 | * last one is our owner. | ||
42 | */ | ||
43 | struct CadetPeerPathEntry *entries; | ||
44 | |||
45 | /** | ||
46 | * Node of this path in the owner's heap. Used to update our position | ||
47 | * in the heap whenever our @e desirability changes. | ||
48 | */ | ||
49 | struct GNUNET_CONTAINER_HeapNode *hn; | ||
50 | |||
51 | /** | ||
52 | * Connections using this path, by destination peer | ||
53 | * (each hop of the path could correspond to an | ||
54 | * active connection). | ||
55 | */ | ||
56 | struct GNUNET_CONTAINER_MultiPeerMap *connections; | ||
57 | |||
58 | /** | ||
59 | * Desirability of the path. How unique is it for the various peers | ||
60 | * on it? | ||
61 | */ | ||
62 | GNUNET_CONTAINER_HeapCostType desirability; | ||
63 | |||
64 | /** | ||
65 | * Length of the @e entries array. | ||
66 | */ | ||
67 | unsigned int entries_length; | ||
68 | |||
69 | }; | ||
70 | |||
71 | |||
32 | 72 | ||
33 | /** | 73 | /** |
34 | * Return how much we like keeping the path. This is an aggregate | 74 | * Return how much we like keeping the path. This is an aggregate |
@@ -44,7 +84,7 @@ | |||
44 | * @return desirability of the path, larger is more desirable | 84 | * @return desirability of the path, larger is more desirable |
45 | */ | 85 | */ |
46 | GNUNET_CONTAINER_HeapCostType | 86 | GNUNET_CONTAINER_HeapCostType |
47 | GCPP_get_desirability (struct CadetPeerPath *path) | 87 | GCPP_get_desirability (const struct CadetPeerPath *path) |
48 | { | 88 | { |
49 | GNUNET_assert (0); | 89 | GNUNET_assert (0); |
50 | return 0; | 90 | return 0; |
@@ -72,23 +112,58 @@ GCPP_acquire (struct CadetPeerPath *path, | |||
72 | 112 | ||
73 | 113 | ||
74 | /** | 114 | /** |
75 | * The given peer @a cp used to own this @a path. However, it is no | 115 | * The owning peer of this path is no longer interested in maintaining |
76 | * longer interested in maintaining it, so the path should be | 116 | * it, so the path should be discarded or shortened (in case a |
77 | * discarded or shortened (in case a previous peer on the path finds | 117 | * previous peer on the path finds the path desirable). |
78 | * the path desirable). | ||
79 | * | 118 | * |
80 | * @param path the path that is being released | 119 | * @param path the path that is being released |
81 | * @param cp original final destination of @a path | ||
82 | */ | 120 | */ |
83 | void | 121 | void |
84 | GCPP_release (struct CadetPeerPath *path, | 122 | GCPP_release (struct CadetPeerPath *path) |
85 | struct CadetPeer *cp) | ||
86 | { | 123 | { |
87 | GNUNET_assert (0); | 124 | GNUNET_assert (0); |
88 | } | 125 | } |
89 | 126 | ||
90 | 127 | ||
91 | /** | 128 | /** |
129 | * Updates the score for an entry on the path based | ||
130 | * on our experiences with using @a path. | ||
131 | * | ||
132 | * @param path the path to update | ||
133 | * @param off offset of the entry to update | ||
134 | * @param delta change in the score to apply | ||
135 | */ | ||
136 | void | ||
137 | GCPP_update_score (struct CadetPeerPath *path, | ||
138 | unsigned int off, | ||
139 | int delta) | ||
140 | { | ||
141 | struct CadetPeerPathEntry *entry; | ||
142 | |||
143 | GNUNET_assert (off < path->entries_length); | ||
144 | entry = &path->entries[off]; | ||
145 | |||
146 | /* Add delta, with checks for overflows */ | ||
147 | if (delta >= 0) | ||
148 | { | ||
149 | if (delta + entry->score < entry->score) | ||
150 | entry->score = INT_MAX; | ||
151 | else | ||
152 | entry->score += delta; | ||
153 | } | ||
154 | else | ||
155 | { | ||
156 | if (delta + entry->score > entry->score) | ||
157 | entry->score = INT_MIN; | ||
158 | else | ||
159 | entry->score += delta; | ||
160 | } | ||
161 | |||
162 | /* FIXME: update path desirability! */ | ||
163 | } | ||
164 | |||
165 | |||
166 | /** | ||
92 | * Create a peer path based on the result of a DHT lookup. | 167 | * Create a peer path based on the result of a DHT lookup. |
93 | * | 168 | * |
94 | * @param get_path path of the get request | 169 | * @param get_path path of the get request |
@@ -103,6 +178,25 @@ GCPP_path_from_dht (const struct GNUNET_PeerIdentity *get_path, | |||
103 | const struct GNUNET_PeerIdentity *put_path, | 178 | const struct GNUNET_PeerIdentity *put_path, |
104 | unsigned int put_path_length) | 179 | unsigned int put_path_length) |
105 | { | 180 | { |
181 | struct CadetPeerPath *path; | ||
182 | |||
183 | path = GNUNET_new (struct CadetPeerPath); | ||
184 | path->entries_length = get_path_length + put_path_length; | ||
185 | path->entries = GNUNET_new_array (path->entries_length, | ||
186 | struct CadetPeerPathEntry); | ||
187 | for (unsigned int i=0;i<get_path_length + put_path_length;i++) | ||
188 | { | ||
189 | struct CadetPeerPathEntry *entry = &path->entries[i]; | ||
190 | const struct GNUNET_PeerIdentity *pid; | ||
191 | |||
192 | pid = (i < get_path_length) ? &get_path[get_path_length - i] : &put_path[path->entries_length - i]; | ||
193 | entry->peer = GCP_get (pid, | ||
194 | GNUNET_YES); | ||
195 | entry->path = path; | ||
196 | GCP_path_entry_add (entry->peer, | ||
197 | entry, | ||
198 | i); | ||
199 | } | ||
106 | GNUNET_break (0); | 200 | GNUNET_break (0); |
107 | return NULL; | 201 | return NULL; |
108 | } | 202 | } |
diff --git a/src/cadet/gnunet-service-cadet-new_paths.h b/src/cadet/gnunet-service-cadet-new_paths.h index 55e521bbf..e00b05a3d 100644 --- a/src/cadet/gnunet-service-cadet-new_paths.h +++ b/src/cadet/gnunet-service-cadet-new_paths.h | |||
@@ -81,7 +81,7 @@ GCPP_get_length (struct CadetPeerPath *path); | |||
81 | * @return desirability of the path, larger is more desirable | 81 | * @return desirability of the path, larger is more desirable |
82 | */ | 82 | */ |
83 | GNUNET_CONTAINER_HeapCostType | 83 | GNUNET_CONTAINER_HeapCostType |
84 | GCPP_get_desirability (struct CadetPeerPath *path); | 84 | GCPP_get_desirability (const struct CadetPeerPath *path); |
85 | 85 | ||
86 | 86 | ||
87 | /** | 87 | /** |
@@ -108,11 +108,9 @@ GCPP_acquire (struct CadetPeerPath *path, | |||
108 | * the path desirable). | 108 | * the path desirable). |
109 | * | 109 | * |
110 | * @param path the path that is being released | 110 | * @param path the path that is being released |
111 | * @param cp original final destination of @a path | ||
112 | */ | 111 | */ |
113 | void | 112 | void |
114 | GCPP_release (struct CadetPeerPath *path, | 113 | GCPP_release (struct CadetPeerPath *path); |
115 | struct CadetPeer *cp); | ||
116 | 114 | ||
117 | 115 | ||
118 | /** | 116 | /** |
diff --git a/src/cadet/gnunet-service-cadet-new_peer.c b/src/cadet/gnunet-service-cadet-new_peer.c index 43e375c75..0ef65b7b6 100644 --- a/src/cadet/gnunet-service-cadet-new_peer.c +++ b/src/cadet/gnunet-service-cadet-new_peer.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "gnunet-service-cadet-new.h" | 37 | #include "gnunet-service-cadet-new.h" |
38 | #include "gnunet-service-cadet-new_dht.h" | 38 | #include "gnunet-service-cadet-new_dht.h" |
39 | #include "gnunet-service-cadet-new_peer.h" | 39 | #include "gnunet-service-cadet-new_peer.h" |
40 | #include "gnunet-service-cadet-new_paths.h" | ||
40 | #include "gnunet-service-cadet-new_tunnels.h" | 41 | #include "gnunet-service-cadet-new_tunnels.h" |
41 | 42 | ||
42 | /** | 43 | /** |
@@ -45,6 +46,12 @@ | |||
45 | #define IDLE_PEER_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5) | 46 | #define IDLE_PEER_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5) |
46 | 47 | ||
47 | /** | 48 | /** |
49 | * How long do we keep paths around if we no longer care about the peer? | ||
50 | */ | ||
51 | #define IDLE_PATH_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2) | ||
52 | |||
53 | |||
54 | /** | ||
48 | * Struct containing all information regarding a given peer | 55 | * Struct containing all information regarding a given peer |
49 | */ | 56 | */ |
50 | struct CadetPeer | 57 | struct CadetPeer |
@@ -72,7 +79,8 @@ struct CadetPeer | |||
72 | struct CadetPeerPathEntry **path_tails; | 79 | struct CadetPeerPathEntry **path_tails; |
73 | 80 | ||
74 | /** | 81 | /** |
75 | * MIN-heap of paths ending at this peer. Ordered by desirability. | 82 | * MIN-heap of paths owned by this peer (they also end at this |
83 | * peer). Ordered by desirability. | ||
76 | */ | 84 | */ |
77 | struct GNUNET_CONTAINER_Heap *path_heap; | 85 | struct GNUNET_CONTAINER_Heap *path_heap; |
78 | 86 | ||
@@ -186,8 +194,6 @@ destroy_peer (void *cls) | |||
186 | } | 194 | } |
187 | /* FIXME: clean up search_delayedXXX! */ | 195 | /* FIXME: clean up search_delayedXXX! */ |
188 | 196 | ||
189 | GNUNET_CONTAINER_multihashmap_destroy (cp->connections); | ||
190 | GNUNET_free_non_null (cp->hello); | ||
191 | if (NULL != cp->hello_offer) | 197 | if (NULL != cp->hello_offer) |
192 | { | 198 | { |
193 | GNUNET_TRANSPORT_offer_hello_cancel (cp->hello_offer); | 199 | GNUNET_TRANSPORT_offer_hello_cancel (cp->hello_offer); |
@@ -198,6 +204,9 @@ destroy_peer (void *cls) | |||
198 | GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion); | 204 | GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion); |
199 | cp->connectivity_suggestion = NULL; | 205 | cp->connectivity_suggestion = NULL; |
200 | } | 206 | } |
207 | GNUNET_CONTAINER_multihashmap_destroy (cp->connections); | ||
208 | GNUNET_CONTAINER_heap_destroy (cp->path_heap); | ||
209 | GNUNET_free_non_null (cp->hello); | ||
201 | GNUNET_free (cp); | 210 | GNUNET_free (cp); |
202 | } | 211 | } |
203 | 212 | ||
@@ -247,6 +256,34 @@ GCP_destroy_all_peers () | |||
247 | * @param cp peer to clean up | 256 | * @param cp peer to clean up |
248 | */ | 257 | */ |
249 | static void | 258 | static void |
259 | consider_peer_destroy (struct CadetPeer *cp); | ||
260 | |||
261 | |||
262 | /** | ||
263 | * We really no longere care about a peer, stop hogging memory with paths to it. | ||
264 | * Afterwards, see if there is more to be cleaned up about this peer. | ||
265 | * | ||
266 | * @param cls a `struct CadetPeer`. | ||
267 | */ | ||
268 | static void | ||
269 | drop_paths (void *cls) | ||
270 | { | ||
271 | struct CadetPeer *cp = cls; | ||
272 | struct CadetPeerPath *path; | ||
273 | |||
274 | cp->destroy_task = NULL; | ||
275 | while (NULL != (path = GNUNET_CONTAINER_heap_remove_root (cp->path_heap))) | ||
276 | GCPP_release (path); | ||
277 | consider_peer_destroy (cp); | ||
278 | } | ||
279 | |||
280 | |||
281 | /** | ||
282 | * This peer may no longer be needed, consider cleaning it up. | ||
283 | * | ||
284 | * @param cp peer to clean up | ||
285 | */ | ||
286 | static void | ||
250 | consider_peer_destroy (struct CadetPeer *cp) | 287 | consider_peer_destroy (struct CadetPeer *cp) |
251 | { | 288 | { |
252 | struct GNUNET_TIME_Relative exp; | 289 | struct GNUNET_TIME_Relative exp; |
@@ -260,17 +297,24 @@ consider_peer_destroy (struct CadetPeer *cp) | |||
260 | return; /* still relevant! */ | 297 | return; /* still relevant! */ |
261 | if (NULL != cp->core_mq) | 298 | if (NULL != cp->core_mq) |
262 | return; /* still relevant! */ | 299 | return; /* still relevant! */ |
263 | if (0 != cp->path_dll_length) | ||
264 | return; /* still relevant! */ | ||
265 | if (0 != GNUNET_CONTAINER_multihashmap_size (cp->connections)) | 300 | if (0 != GNUNET_CONTAINER_multihashmap_size (cp->connections)) |
266 | return; /* still relevant! */ | 301 | return; /* still relevant! */ |
302 | if (0 < GNUNET_CONTAINER_heap_get_size (cp->path_heap)) | ||
303 | { | ||
304 | cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PATH_TIMEOUT, | ||
305 | &drop_paths, | ||
306 | cp); | ||
307 | return; | ||
308 | } | ||
309 | if (0 < cp->path_dll_length) | ||
310 | return; /* still relevant! */ | ||
267 | if (NULL != cp->hello) | 311 | if (NULL != cp->hello) |
268 | { | 312 | { |
269 | /* relevant only until HELLO expires */ | 313 | /* relevant only until HELLO expires */ |
270 | exp = GNUNET_TIME_absolute_get_remaining (GNUNET_HELLO_get_last_expiration (cp->hello)); | 314 | exp = GNUNET_TIME_absolute_get_remaining (GNUNET_HELLO_get_last_expiration (cp->hello)); |
271 | cp->destroy_task = GNUNET_SCHEDULER_add_delayed (exp, | 315 | cp->destroy_task = GNUNET_SCHEDULER_add_delayed (exp, |
272 | &destroy_peer, | 316 | &destroy_peer, |
273 | cp); | 317 | cp); |
274 | return; | 318 | return; |
275 | } | 319 | } |
276 | cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PEER_TIMEOUT, | 320 | cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PEER_TIMEOUT, |
@@ -337,7 +381,7 @@ GCP_path_entry_remove (struct CadetPeer *cp, | |||
337 | */ | 381 | */ |
338 | static void | 382 | static void |
339 | dht_result_cb (void *cls, | 383 | dht_result_cb (void *cls, |
340 | const struct CadetPeerPath *path) | 384 | struct CadetPeerPath *path) |
341 | { | 385 | { |
342 | struct CadetPeer *cp = cls; | 386 | struct CadetPeer *cp = cls; |
343 | GNUNET_CONTAINER_HeapCostType desirability; | 387 | GNUNET_CONTAINER_HeapCostType desirability; |
@@ -368,8 +412,7 @@ dht_result_cb (void *cls, | |||
368 | { | 412 | { |
369 | /* Now we have way too many, drop least desirable */ | 413 | /* Now we have way too many, drop least desirable */ |
370 | root = GNUNET_CONTAINER_heap_remove_root (cp->path_heap); | 414 | root = GNUNET_CONTAINER_heap_remove_root (cp->path_heap); |
371 | GCPP_release (path, | 415 | GCPP_release (path); |
372 | cp); | ||
373 | } | 416 | } |
374 | } | 417 | } |
375 | 418 | ||
@@ -464,6 +507,7 @@ GCP_get (const struct GNUNET_PeerIdentity *peer_id, | |||
464 | cp->pid = *peer_id; | 507 | cp->pid = *peer_id; |
465 | cp->connections = GNUNET_CONTAINER_multihashmap_create (32, | 508 | cp->connections = GNUNET_CONTAINER_multihashmap_create (32, |
466 | GNUNET_YES); | 509 | GNUNET_YES); |
510 | cp->path_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | ||
467 | cp->search_h = NULL; // FIXME: start search immediately!? | 511 | cp->search_h = NULL; // FIXME: start search immediately!? |
468 | cp->connectivity_suggestion = NULL; // FIXME: request with ATS!? | 512 | cp->connectivity_suggestion = NULL; // FIXME: request with ATS!? |
469 | 513 | ||