diff options
author | Bart Polot <bart@net.in.tum.de> | 2011-09-20 17:22:58 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2011-09-20 17:22:58 +0000 |
commit | 62cf5f2f6da72d38adac69e239400edd501ef9cb (patch) | |
tree | d60c7b9e70328628d81ad2176a5cc9f96c441c37 /src/mesh/mesh_tunnel_tree.c | |
parent | 73e047c74d351257f8b6cf0815a56ff650520cc1 (diff) | |
download | gnunet-62cf5f2f6da72d38adac69e239400edd501ef9cb.tar.gz gnunet-62cf5f2f6da72d38adac69e239400edd501ef9cb.zip |
Cleaned and fixed refactoring to improve separation, only 3 structs are now shared
Diffstat (limited to 'src/mesh/mesh_tunnel_tree.c')
-rw-r--r-- | src/mesh/mesh_tunnel_tree.c | 234 |
1 files changed, 56 insertions, 178 deletions
diff --git a/src/mesh/mesh_tunnel_tree.c b/src/mesh/mesh_tunnel_tree.c index 10298ca5a..e838cefc1 100644 --- a/src/mesh/mesh_tunnel_tree.c +++ b/src/mesh/mesh_tunnel_tree.c | |||
@@ -28,10 +28,6 @@ | |||
28 | #include "mesh_tunnel_tree.h" | 28 | #include "mesh_tunnel_tree.h" |
29 | 29 | ||
30 | 30 | ||
31 | extern GNUNET_PEER_Id myid; | ||
32 | extern struct GNUNET_PeerIdentity my_full_id; | ||
33 | |||
34 | |||
35 | /** | 31 | /** |
36 | * Invert the path | 32 | * Invert the path |
37 | * | 33 | * |
@@ -72,19 +68,19 @@ path_destroy (struct MeshPeerPath *p) | |||
72 | /** | 68 | /** |
73 | * Find the first peer whom to send a packet to go down this path | 69 | * Find the first peer whom to send a packet to go down this path |
74 | * | 70 | * |
75 | * @param t The tunnel to use | 71 | * @param t The tunnel tree to use |
76 | * @param peer The peerinfo of the peer we are trying to reach | 72 | * @param peer The peerinfo of the peer we are trying to reach |
77 | * | 73 | * |
78 | * @return peerinfo of the peer who is the first hop in the tunnel | 74 | * @return peerinfo of the peer who is the first hop in the tunnel |
79 | * NULL on error | 75 | * NULL on error |
80 | */ | 76 | */ |
81 | struct GNUNET_PeerIdentity * | 77 | struct GNUNET_PeerIdentity * |
82 | path_get_first_hop (struct MeshTunnel *t, struct MeshPeerInfo *peer) | 78 | path_get_first_hop (struct MeshTunnelTree *t, GNUNET_PEER_Id peer) |
83 | { | 79 | { |
84 | struct GNUNET_PeerIdentity id; | 80 | struct GNUNET_PeerIdentity id; |
85 | 81 | ||
86 | GNUNET_PEER_resolve (peer->id, &id); | 82 | GNUNET_PEER_resolve (peer, &id); |
87 | return GNUNET_CONTAINER_multihashmap_get (t->tree->first_hops, | 83 | return GNUNET_CONTAINER_multihashmap_get (t->first_hops, |
88 | &id.hashPubKey); | 84 | &id.hashPubKey); |
89 | } | 85 | } |
90 | 86 | ||
@@ -109,7 +105,7 @@ path_get_length (struct MeshPeerPath *path) | |||
109 | /** | 105 | /** |
110 | * Get the cost of the path relative to the already built tunnel tree | 106 | * Get the cost of the path relative to the already built tunnel tree |
111 | * | 107 | * |
112 | * @param t The tunnel to which compare | 108 | * @param t The tunnel tree to which compare |
113 | * @param path The individual path to reach a peer | 109 | * @param path The individual path to reach a peer |
114 | * | 110 | * |
115 | * @return Number of hops to reach destination, UINT_MAX in case the peer is not | 111 | * @return Number of hops to reach destination, UINT_MAX in case the peer is not |
@@ -118,97 +114,13 @@ path_get_length (struct MeshPeerPath *path) | |||
118 | * TODO: remove dummy implementation, look into the tunnel tree | 114 | * TODO: remove dummy implementation, look into the tunnel tree |
119 | */ | 115 | */ |
120 | unsigned int | 116 | unsigned int |
121 | path_get_cost (struct MeshTunnel *t, struct MeshPeerPath *path) | 117 | path_get_cost (struct MeshTunnelTree *t, struct MeshPeerPath *path) |
122 | { | 118 | { |
123 | return path_get_length (path); | 119 | return path_get_length (path); |
124 | } | 120 | } |
125 | 121 | ||
126 | 122 | ||
127 | /** | 123 | /** |
128 | * Add the path to the peer and update the path used to reach it in case this | ||
129 | * is the shortest. | ||
130 | * | ||
131 | * @param peer_info Destination peer to add the path to. | ||
132 | * @param path New path to add. Last peer must be the peer in arg 1. | ||
133 | * Path will be either used of freed if already known. | ||
134 | * | ||
135 | * TODO: trim the part from origin to us? Add it as path to origin? | ||
136 | */ | ||
137 | void | ||
138 | path_add_to_peer (struct MeshPeerInfo *peer_info, struct MeshPeerPath *path) | ||
139 | { | ||
140 | struct MeshPeerPath *aux; | ||
141 | unsigned int l; | ||
142 | unsigned int l2; | ||
143 | |||
144 | if (NULL == peer_info || NULL == path) | ||
145 | { | ||
146 | GNUNET_break (0); | ||
147 | return; | ||
148 | } | ||
149 | |||
150 | l = path_get_length (path); | ||
151 | |||
152 | for (aux = peer_info->path_head; aux != NULL; aux = aux->next) | ||
153 | { | ||
154 | l2 = path_get_length (aux); | ||
155 | if (l2 > l) | ||
156 | { | ||
157 | GNUNET_CONTAINER_DLL_insert_before (peer_info->path_head, | ||
158 | peer_info->path_tail, aux, path); | ||
159 | } | ||
160 | else | ||
161 | { | ||
162 | if (l2 == l && memcmp(path->peers, aux->peers, l) == 0) | ||
163 | { | ||
164 | path_destroy(path); | ||
165 | return; | ||
166 | } | ||
167 | } | ||
168 | } | ||
169 | GNUNET_CONTAINER_DLL_insert_tail (peer_info->path_head, peer_info->path_tail, | ||
170 | path); | ||
171 | return; | ||
172 | } | ||
173 | |||
174 | |||
175 | /** | ||
176 | * Send keepalive packets for a peer | ||
177 | * | ||
178 | * @param cls unused | ||
179 | * @param tc unused | ||
180 | * | ||
181 | * FIXME path | ||
182 | */ | ||
183 | void | ||
184 | path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
185 | { | ||
186 | struct MeshTunnel *t = cls; | ||
187 | |||
188 | // struct GNUNET_PeerIdentity id; | ||
189 | |||
190 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
191 | { | ||
192 | return; | ||
193 | } | ||
194 | /* FIXME implement multicast keepalive. Just an empty multicast packet? */ | ||
195 | // GNUNET_PEER_resolve (path_get_first_hop (path->t, path->peer)->id, &id); | ||
196 | // GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, | ||
197 | // GNUNET_TIME_UNIT_FOREVER_REL, &id, | ||
198 | // sizeof (struct GNUNET_MESH_ManipulatePath) | ||
199 | // + | ||
200 | // (path->path->length * | ||
201 | // sizeof (struct GNUNET_PeerIdentity)), | ||
202 | // &send_core_create_path, | ||
203 | // t); | ||
204 | t->path_refresh_task = | ||
205 | GNUNET_SCHEDULER_add_delayed (t->tree->refresh, &path_refresh, t); | ||
206 | return; | ||
207 | } | ||
208 | |||
209 | |||
210 | |||
211 | /** | ||
212 | * Recursively find the given peer in the tree. | 124 | * Recursively find the given peer in the tree. |
213 | * | 125 | * |
214 | * @param t Tunnel where to look for the peer. | 126 | * @param t Tunnel where to look for the peer. |
@@ -216,10 +128,10 @@ path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
216 | * | 128 | * |
217 | * @return Pointer to the node of the peer. NULL if not found. | 129 | * @return Pointer to the node of the peer. NULL if not found. |
218 | */ | 130 | */ |
219 | struct MeshTunnelPathNode * | 131 | struct MeshTunnelTreeNode * |
220 | tunnel_find_peer (struct MeshTunnelPathNode *root, GNUNET_PEER_Id peer_id) | 132 | tunnel_find_peer (struct MeshTunnelTreeNode *root, GNUNET_PEER_Id peer_id) |
221 | { | 133 | { |
222 | struct MeshTunnelPathNode *n; | 134 | struct MeshTunnelTreeNode *n; |
223 | unsigned int i; | 135 | unsigned int i; |
224 | 136 | ||
225 | if (root->peer == peer_id) | 137 | if (root->peer == peer_id) |
@@ -238,30 +150,34 @@ tunnel_find_peer (struct MeshTunnelPathNode *root, GNUNET_PEER_Id peer_id) | |||
238 | * Recusively mark peer and children as disconnected, notify client | 150 | * Recusively mark peer and children as disconnected, notify client |
239 | * | 151 | * |
240 | * @param parent Node to be clean, potentially with children | 152 | * @param parent Node to be clean, potentially with children |
241 | * @param nc Notification context to use to alert the client | 153 | * @param cb Callback to use to notify about disconnected peers. |
242 | */ | 154 | */ |
243 | void | 155 | void |
244 | tunnel_mark_peers_disconnected (struct MeshTunnelPathNode *parent, | 156 | tunnel_mark_peers_disconnected (struct MeshTunnelTreeNode *parent, |
245 | struct GNUNET_SERVER_NotificationContext *nc) | 157 | MeshNodeDisconnectCB cb) |
246 | { | 158 | { |
247 | struct GNUNET_MESH_PeerControl msg; | ||
248 | unsigned int i; | 159 | unsigned int i; |
249 | 160 | ||
161 | if (MESH_PEER_READY == parent->status) | ||
162 | { | ||
163 | cb (parent); | ||
164 | } | ||
250 | parent->status = MESH_PEER_RECONNECTING; | 165 | parent->status = MESH_PEER_RECONNECTING; |
251 | for (i = 0; i < parent->nchildren; i++) | 166 | for (i = 0; i < parent->nchildren; i++) |
252 | { | 167 | { |
253 | tunnel_mark_peers_disconnected (&parent->children[i], nc); | 168 | tunnel_mark_peers_disconnected (&parent->children[i], cb); |
254 | } | 169 | } |
255 | if (NULL == parent->t->client) | 170 | // struct GNUNET_MESH_PeerControl msg; |
256 | return; | 171 | // if (NULL == parent->t->client) |
257 | msg.header.size = htons (sizeof (msg)); | 172 | // return; |
258 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL); | 173 | // msg.header.size = htons (sizeof (msg)); |
259 | msg.tunnel_id = htonl (parent->t->local_tid); | 174 | // msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL); |
260 | GNUNET_PEER_resolve (parent->peer, &msg.peer); | 175 | // msg.tunnel_id = htonl (parent->t->local_tid); |
261 | if (NULL == nc) | 176 | // GNUNET_PEER_resolve (parent->peer, &msg.peer); |
262 | return; | 177 | // if (NULL == nc) |
263 | GNUNET_SERVER_notification_context_unicast (nc, parent->t->client->handle, | 178 | // return; |
264 | &msg.header, GNUNET_NO); | 179 | // GNUNET_SERVER_notification_context_unicast (nc, parent->t->client->handle, |
180 | // &msg.header, GNUNET_NO); | ||
265 | } | 181 | } |
266 | 182 | ||
267 | 183 | ||
@@ -272,23 +188,23 @@ tunnel_mark_peers_disconnected (struct MeshTunnelPathNode *parent, | |||
272 | * The destination peer is NOT destroyed, it is returned in order to either set | 188 | * The destination peer is NOT destroyed, it is returned in order to either set |
273 | * a new path to it or destroy it explicitly, taking care of it's child nodes. | 189 | * a new path to it or destroy it explicitly, taking care of it's child nodes. |
274 | * | 190 | * |
275 | * @param t Tunnel where to delete the path from. | 191 | * @param t Tunnel tree where to delete the path from. |
276 | * @param peer Destination peer whose path we want to remove. | 192 | * @param peer Destination peer whose path we want to remove. |
277 | * @param nc Notification context to alert the client of disconnected peers. | 193 | * @param cb Callback to use to notify about disconnected peers. |
278 | * | 194 | * |
279 | * @return pointer to the pathless node, NULL on error | 195 | * @return pointer to the pathless node, NULL on error |
280 | */ | 196 | */ |
281 | struct MeshTunnelPathNode * | 197 | struct MeshTunnelTreeNode * |
282 | tunnel_del_path (struct MeshTunnel *t, GNUNET_PEER_Id peer_id, | 198 | tunnel_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id, |
283 | struct GNUNET_SERVER_NotificationContext *nc) | 199 | MeshNodeDisconnectCB cb) |
284 | { | 200 | { |
285 | struct MeshTunnelPathNode *parent; | 201 | struct MeshTunnelTreeNode *parent; |
286 | struct MeshTunnelPathNode *node; | 202 | struct MeshTunnelTreeNode *node; |
287 | struct MeshTunnelPathNode *n; | 203 | struct MeshTunnelTreeNode *n; |
288 | 204 | ||
289 | if (peer_id == t->tree->root->peer) | 205 | if (peer_id == t->root->peer) |
290 | return NULL; | 206 | return NULL; |
291 | node = n = tunnel_find_peer (t->tree->me, peer_id); | 207 | node = n = tunnel_find_peer (t->me, peer_id); |
292 | if (NULL == n) | 208 | if (NULL == n) |
293 | return NULL; | 209 | return NULL; |
294 | parent = n->parent; | 210 | parent = n->parent; |
@@ -306,7 +222,7 @@ tunnel_del_path (struct MeshTunnel *t, GNUNET_PEER_Id peer_id, | |||
306 | parent->nchildren--; | 222 | parent->nchildren--; |
307 | parent->children = GNUNET_realloc (parent->children, parent->nchildren); | 223 | parent->children = GNUNET_realloc (parent->children, parent->nchildren); |
308 | 224 | ||
309 | tunnel_mark_peers_disconnected (node, nc); | 225 | tunnel_mark_peers_disconnected (node, cb); |
310 | 226 | ||
311 | return node; | 227 | return node; |
312 | } | 228 | } |
@@ -323,13 +239,13 @@ tunnel_del_path (struct MeshTunnel *t, GNUNET_PEER_Id peer_id, | |||
323 | * Path must be destroyed afterwards. | 239 | * Path must be destroyed afterwards. |
324 | */ | 240 | */ |
325 | struct MeshPeerPath * | 241 | struct MeshPeerPath * |
326 | tunnel_get_path_to_peer(struct MeshTunnel *t, struct MeshPeerInfo *peer_info) | 242 | tunnel_get_path_to_peer(struct MeshTunnelTree *t, GNUNET_PEER_Id peer) |
327 | { | 243 | { |
328 | struct MeshTunnelPathNode *n; | 244 | struct MeshTunnelTreeNode *n; |
329 | struct MeshPeerPath *p; | 245 | struct MeshPeerPath *p; |
330 | GNUNET_PEER_Id myid = t->tree->me->peer; | 246 | GNUNET_PEER_Id myid = t->me->peer; |
331 | 247 | ||
332 | n = tunnel_find_peer(t->tree->me, peer_info->id); | 248 | n = tunnel_find_peer(t->me, peer); |
333 | p = GNUNET_malloc(sizeof(struct MeshPeerPath)); | 249 | p = GNUNET_malloc(sizeof(struct MeshPeerPath)); |
334 | 250 | ||
335 | /* Building the path (inverted!) */ | 251 | /* Building the path (inverted!) */ |
@@ -354,8 +270,7 @@ tunnel_get_path_to_peer(struct MeshTunnel *t, struct MeshPeerInfo *peer_info) | |||
354 | * | 270 | * |
355 | * @param t Tunnel where to add the new path. | 271 | * @param t Tunnel where to add the new path. |
356 | * @param p Path to be integrated. | 272 | * @param p Path to be integrated. |
357 | * @param nc Notification context to alert clients of peers | 273 | * @param cb Callback to use to notify about peers temporarily disconnecting |
358 | * temporarily disconnected | ||
359 | * | 274 | * |
360 | * @return GNUNET_OK in case of success. | 275 | * @return GNUNET_OK in case of success. |
361 | * GNUNET_SYSERR in case of error. | 276 | * GNUNET_SYSERR in case of error. |
@@ -365,20 +280,21 @@ tunnel_get_path_to_peer(struct MeshTunnel *t, struct MeshPeerInfo *peer_info) | |||
365 | * - do not disconnect peers until new path is created & connected | 280 | * - do not disconnect peers until new path is created & connected |
366 | */ | 281 | */ |
367 | int | 282 | int |
368 | tunnel_add_path (struct MeshTunnel *t, const struct MeshPeerPath *p) | 283 | tunnel_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, |
284 | MeshNodeDisconnectCB cb) | ||
369 | { | 285 | { |
370 | struct MeshTunnelPathNode *parent; | 286 | struct MeshTunnelTreeNode *parent; |
371 | struct MeshTunnelPathNode *oldnode; | 287 | struct MeshTunnelTreeNode *oldnode; |
372 | struct MeshTunnelPathNode *n; | 288 | struct MeshTunnelTreeNode *n; |
373 | struct GNUNET_PeerIdentity id; | 289 | struct GNUNET_PeerIdentity id; |
374 | struct GNUNET_PeerIdentity *hop; | 290 | struct GNUNET_PeerIdentity *hop; |
375 | GNUNET_PEER_Id myid = t->tree->me->peer; | 291 | GNUNET_PEER_Id myid = t->me->peer; |
376 | int me; | 292 | int me; |
377 | unsigned int i; | 293 | unsigned int i; |
378 | unsigned int j; | 294 | unsigned int j; |
379 | 295 | ||
380 | GNUNET_assert(0 != p->length); | 296 | GNUNET_assert(0 != p->length); |
381 | n = t->tree->root; | 297 | n = t->root; |
382 | if (n->peer != p->peers[0]) | 298 | if (n->peer != p->peers[0]) |
383 | { | 299 | { |
384 | GNUNET_break (0); | 300 | GNUNET_break (0); |
@@ -386,7 +302,7 @@ tunnel_add_path (struct MeshTunnel *t, const struct MeshPeerPath *p) | |||
386 | } | 302 | } |
387 | if (1 == p->length) | 303 | if (1 == p->length) |
388 | return GNUNET_OK; | 304 | return GNUNET_OK; |
389 | oldnode = tunnel_del_path (t, p->peers[p->length - 1], NULL); | 305 | oldnode = tunnel_del_path (t, p->peers[p->length - 1], cb); |
390 | /* Look for the first node that is not already present in the tree | 306 | /* Look for the first node that is not already present in the tree |
391 | * | 307 | * |
392 | * Assuming that the tree is somewhat balanced, O(log n * log N). | 308 | * Assuming that the tree is somewhat balanced, O(log n * log N). |
@@ -423,17 +339,17 @@ tunnel_add_path (struct MeshTunnel *t, const struct MeshPeerPath *p) | |||
423 | parent->nchildren++; | 339 | parent->nchildren++; |
424 | parent->children = GNUNET_realloc (parent->children, | 340 | parent->children = GNUNET_realloc (parent->children, |
425 | parent->nchildren * | 341 | parent->nchildren * |
426 | sizeof(struct MeshTunnelPathNode)); | 342 | sizeof(struct MeshTunnelTreeNode)); |
427 | n = &parent->children[parent->nchildren - 1]; | 343 | n = &parent->children[parent->nchildren - 1]; |
428 | if (i == p->length - 1 && NULL != oldnode) | 344 | if (i == p->length - 1 && NULL != oldnode) |
429 | { | 345 | { |
430 | /* Assignation and free can be misleading, using explicit mempcy */ | 346 | /* Assignation and free can be misleading, using explicit mempcy */ |
431 | memcpy (n, oldnode, sizeof (struct MeshTunnelPathNode)); | 347 | memcpy (n, oldnode, sizeof (struct MeshTunnelTreeNode)); |
432 | GNUNET_free (oldnode); | 348 | GNUNET_free (oldnode); |
433 | } | 349 | } |
434 | else | 350 | else |
435 | { | 351 | { |
436 | n->t = t; | 352 | n->t = t->t; |
437 | n->status = MESH_PEER_RELAY; | 353 | n->status = MESH_PEER_RELAY; |
438 | n->peer = p->peers[i]; | 354 | n->peer = p->peers[i]; |
439 | } | 355 | } |
@@ -448,47 +364,9 @@ tunnel_add_path (struct MeshTunnel *t, const struct MeshPeerPath *p) | |||
448 | GNUNET_PEER_resolve (p->peers[p->length - 1], &id); | 364 | GNUNET_PEER_resolve (p->peers[p->length - 1], &id); |
449 | hop = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); | 365 | hop = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); |
450 | GNUNET_PEER_resolve (p->peers[me + 1], hop); | 366 | GNUNET_PEER_resolve (p->peers[me + 1], hop); |
451 | GNUNET_CONTAINER_multihashmap_put (t->tree->first_hops, &id.hashPubKey, | 367 | GNUNET_CONTAINER_multihashmap_put (t->first_hops, &id.hashPubKey, |
452 | hop, | 368 | hop, |
453 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 369 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); |
454 | } | 370 | } |
455 | return GNUNET_OK; | 371 | return GNUNET_OK; |
456 | } | 372 | } |
457 | |||
458 | |||
459 | /** | ||
460 | * Add a peer to a tunnel, accomodating paths accordingly and initializing all | ||
461 | * needed rescources. | ||
462 | * | ||
463 | * @param t Tunnel we want to add a new peer to | ||
464 | * @param peer PeerInfo of the peer being added | ||
465 | * | ||
466 | */ | ||
467 | void | ||
468 | tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer) | ||
469 | { | ||
470 | struct MeshPeerPath *p; | ||
471 | struct MeshPeerPath *best_p; | ||
472 | unsigned int best_cost; | ||
473 | unsigned int cost; | ||
474 | |||
475 | GNUNET_array_append (peer->tunnels, peer->ntunnels, t); | ||
476 | if (NULL == (p = peer->path_head)) | ||
477 | return; | ||
478 | |||
479 | best_p = p; | ||
480 | best_cost = UINT_MAX; | ||
481 | while (NULL != p) | ||
482 | { | ||
483 | if ((cost = path_get_cost (t, p)) < best_cost) | ||
484 | { | ||
485 | best_cost = cost; | ||
486 | best_p = p; | ||
487 | } | ||
488 | p = p->next; | ||
489 | } | ||
490 | tunnel_add_path (t, best_p); | ||
491 | if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task) | ||
492 | t->path_refresh_task = | ||
493 | GNUNET_SCHEDULER_add_delayed (t->tree->refresh, &path_refresh, t); | ||
494 | } | ||