aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cadet/gnunet-service-cadet-new.h12
-rw-r--r--src/cadet/gnunet-service-cadet-new_dht.h4
-rw-r--r--src/cadet/gnunet-service-cadet-new_paths.c110
-rw-r--r--src/cadet/gnunet-service-cadet-new_paths.h6
-rw-r--r--src/cadet/gnunet-service-cadet-new_peer.c64
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 */
56typedef void 56typedef 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 */
36struct 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 */
46GNUNET_CONTAINER_HeapCostType 86GNUNET_CONTAINER_HeapCostType
47GCPP_get_desirability (struct CadetPeerPath *path) 87GCPP_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 */
83void 121void
84GCPP_release (struct CadetPeerPath *path, 122GCPP_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 */
136void
137GCPP_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 */
83GNUNET_CONTAINER_HeapCostType 83GNUNET_CONTAINER_HeapCostType
84GCPP_get_desirability (struct CadetPeerPath *path); 84GCPP_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 */
113void 112void
114GCPP_release (struct CadetPeerPath *path, 113GCPP_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 */
50struct CadetPeer 57struct 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 */
249static void 258static void
259consider_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 */
268static void
269drop_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 */
286static void
250consider_peer_destroy (struct CadetPeer *cp) 287consider_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 */
338static void 382static void
339dht_result_cb (void *cls, 383dht_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