aboutsummaryrefslogtreecommitdiff
path: root/src/mesh
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesh')
-rw-r--r--src/mesh/gnunet-service-mesh.c440
-rw-r--r--src/mesh/mesh.h381
-rw-r--r--src/mesh/mesh_tunnel_tree.c234
-rw-r--r--src/mesh/mesh_tunnel_tree.h176
-rw-r--r--src/mesh/test_mesh_path_api.c2
5 files changed, 616 insertions, 617 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index 75fa973e0..811553e08 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -62,6 +62,298 @@
62 GNUNET_TIME_UNIT_SECONDS,\ 62 GNUNET_TIME_UNIT_SECONDS,\
63 5) 63 5)
64 64
65
66/******************************************************************************/
67/************************ DATA STRUCTURES ****************************/
68/******************************************************************************/
69
70/** FWD declaration */
71struct MeshPeerInfo;
72
73/**
74 * Struct containing all info possibly needed to build a package when called
75 * back by core.
76 */
77struct MeshDataDescriptor
78{
79 /** ID of the tunnel this packet travels in */
80 struct MESH_TunnelID *origin;
81
82 /** Ultimate destination of the packet */
83 GNUNET_PEER_Id destination;
84
85 /** Number of identical messages sent to different hops (multicast) */
86 unsigned int copies;
87
88 /** Size of the data */
89 size_t size;
90
91 /** Client that asked for the transmission, if any */
92 struct GNUNET_SERVER_Client *client;
93
94 /** Who was is message being sent to */
95 struct MeshPeerInfo *peer;
96
97 /** Which handler was used to request the transmission */
98 unsigned int handler_n;
99
100 /* Data at the end */
101};
102
103
104/**
105 * Struct containing all information regarding a given peer
106 */
107struct MeshPeerInfo
108{
109 /**
110 * ID of the peer
111 */
112 GNUNET_PEER_Id id;
113
114 /**
115 * Last time we heard from this peer
116 */
117 struct GNUNET_TIME_Absolute last_contact;
118
119 /**
120 * Number of attempts to reconnect so far
121 */
122 int n_reconnect_attempts;
123
124 /**
125 * Paths to reach the peer, ordered by ascending hop count
126 */
127 struct MeshPeerPath *path_head;
128
129 /**
130 * Paths to reach the peer, ordered by ascending hop count
131 */
132 struct MeshPeerPath *path_tail;
133
134 /**
135 * Handle to stop the DHT search for a path to this peer
136 */
137 struct GNUNET_DHT_GetHandle *dhtget;
138
139 /**
140 * Handles to stop queued transmissions for this peer
141 */
142 struct GNUNET_CORE_TransmitHandle *core_transmit[CORE_QUEUE_SIZE];
143
144 /**
145 * Pointer to info stuctures used as cls for queued transmissions
146 */
147 struct MeshDataDescriptor *infos[CORE_QUEUE_SIZE];
148
149 /**
150 * Array of tunnels this peer participates in
151 * (most probably a small amount, therefore not a hashmap)
152 * When the path to the peer changes, notify these tunnels to let them
153 * re-adjust their path trees.
154 */
155 struct MeshTunnel **tunnels;
156
157 /**
158 * Number of tunnels above
159 */
160 unsigned int ntunnels;
161};
162
163
164/**
165 * Data scheduled to transmit (to local client or remote peer)
166 */
167struct MeshQueue
168{
169 /**
170 * Double linked list
171 */
172 struct MeshQueue *next;
173 struct MeshQueue *prev;
174
175 /**
176 * Target of the data (NULL if target is client)
177 */
178 struct MeshPeerInfo *peer;
179
180 /**
181 * Client to send the data to (NULL if target is peer)
182 */
183 struct MeshClient *client;
184
185 /**
186 * Size of the message to transmit
187 */
188 unsigned int size;
189
190 /**
191 * How old is the data?
192 */
193 struct GNUNET_TIME_Absolute timestamp;
194
195 /**
196 * Data itself
197 */
198 struct GNUNET_MessageHeader *data;
199};
200
201/**
202 * Globally unique tunnel identification (owner + number)
203 * DO NOT USE OVER THE NETWORK
204 */
205struct MESH_TunnelID
206{
207 /**
208 * Node that owns the tunnel
209 */
210 GNUNET_PEER_Id oid;
211
212 /**
213 * Tunnel number to differentiate all the tunnels owned by the node oid
214 * ( tid < GNUNET_MESH_LOCAL_TUNNEL_ID_CLI )
215 */
216 MESH_TunnelNumber tid;
217};
218
219
220struct MeshClient; /* FWD declaration */
221
222/**
223 * Struct containing all information regarding a tunnel
224 * For an intermediate node the improtant info used will be:
225 * - id Tunnel unique identification
226 * - paths[0] To know where to send it next
227 * - metainfo: ready, speeds, accounting
228 */
229struct MeshTunnel
230{
231 /**
232 * Tunnel ID
233 */
234 struct MESH_TunnelID id;
235
236 /**
237 * Local tunnel number ( >= GNUNET_MESH_LOCAL_TUNNEL_ID_CLI or 0 )
238 */
239 MESH_TunnelNumber local_tid;
240
241 /**
242 * Last time the tunnel was used
243 */
244 struct GNUNET_TIME_Absolute timestamp;
245
246 /**
247 * Peers in the tunnel, indexed by PeerIdentity -> (MeshPeerInfo)
248 */
249 struct GNUNET_CONTAINER_MultiHashMap *peers;
250
251 /**
252 * Number of peers that are connected and potentially ready to receive data
253 */
254 unsigned int peers_ready;
255
256 /**
257 * Number of peers that have been added to the tunnel
258 */
259 unsigned int peers_total;
260
261 /**
262 * Client owner of the tunnel, if any
263 */
264 struct MeshClient *client;
265
266 /**
267 * Messages ready to transmit
268 */
269 struct MeshQueue *queue_head;
270 struct MeshQueue *queue_tail;
271
272 /**
273 * Tunnel paths
274 */
275 struct MeshTunnelTree *tree;
276
277 /**
278 * Task to keep the used paths alive
279 */
280 GNUNET_SCHEDULER_TaskIdentifier path_refresh_task;
281};
282
283
284/**
285 * Info needed to work with tunnel paths and peers
286 */
287struct MeshPathInfo
288{
289 /**
290 * Tunnel
291 */
292 struct MeshTunnel *t;
293
294 /**
295 * Destination peer
296 */
297 struct MeshPeerInfo *peer;
298
299 /**
300 * Path itself
301 */
302 struct MeshPeerPath *path;
303};
304
305
306/**
307 * Struct containing information about a client of the service
308 */
309struct MeshClient
310{
311 /**
312 * Linked list
313 */
314 struct MeshClient *next;
315 struct MeshClient *prev;
316
317 /**
318 * Tunnels that belong to this client, indexed by local id
319 */
320 struct GNUNET_CONTAINER_MultiHashMap *tunnels;
321
322 /**
323 * Handle to communicate with the client
324 */
325 struct GNUNET_SERVER_Client *handle;
326
327 /**
328 * Applications that this client has claimed to provide
329 */
330 struct GNUNET_CONTAINER_MultiHashMap *apps;
331
332 /**
333 * Messages that this client has declared interest in
334 */
335 struct GNUNET_CONTAINER_MultiHashMap *types;
336
337 /**
338 * Used to search peers offering a service
339 */
340 struct GNUNET_DHT_GetHandle *dht_get_type;
341
342#if MESH_DEBUG
343 /**
344 * ID of the client, for debug messages
345 */
346 unsigned int id;
347#endif
348
349};
350
351
352
353/******************************************************************************/
354/************************ DEBUG FUNCTIONS ****************************/
355/******************************************************************************/
356
65#if MESH_DEBUG 357#if MESH_DEBUG
66/** 358/**
67 * GNUNET_SCHEDULER_Task for printing a message after some operation is done 359 * GNUNET_SCHEDULER_Task for printing a message after some operation is done
@@ -199,7 +491,7 @@ iterate_collect_neighbors (void *cls, const GNUNET_HashCode * key, void *value)
199 { 491 {
200 return GNUNET_YES; 492 return GNUNET_YES;
201 } 493 }
202 id = path_get_first_hop (neighbors->t, peer_info); 494 id = path_get_first_hop (neighbors->t->tree, peer_info->id);
203 peer_id = GNUNET_PEER_search(id); 495 peer_id = GNUNET_PEER_search(id);
204 for (i = 0; i < neighbors->path->length; i++) 496 for (i = 0; i < neighbors->path->length; i++)
205 { 497 {
@@ -443,6 +735,54 @@ path_remove_from_peer (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
443 735
444 736
445/** 737/**
738 * Add the path to the peer and update the path used to reach it in case this
739 * is the shortest.
740 *
741 * @param peer_info Destination peer to add the path to.
742 * @param path New path to add. Last peer must be the peer in arg 1.
743 * Path will be either used of freed if already known.
744 *
745 * TODO: trim the part from origin to us? Add it as path to origin?
746 */
747void
748path_add_to_peer (struct MeshPeerInfo *peer_info, struct MeshPeerPath *path)
749{
750 struct MeshPeerPath *aux;
751 unsigned int l;
752 unsigned int l2;
753
754 if (NULL == peer_info || NULL == path)
755 {
756 GNUNET_break (0);
757 return;
758 }
759
760 l = path_get_length (path);
761
762 for (aux = peer_info->path_head; aux != NULL; aux = aux->next)
763 {
764 l2 = path_get_length (aux);
765 if (l2 > l)
766 {
767 GNUNET_CONTAINER_DLL_insert_before (peer_info->path_head,
768 peer_info->path_tail, aux, path);
769 }
770 else
771 {
772 if (l2 == l && memcmp(path->peers, aux->peers, l) == 0)
773 {
774 path_destroy(path);
775 return;
776 }
777 }
778 }
779 GNUNET_CONTAINER_DLL_insert_tail (peer_info->path_head, peer_info->path_tail,
780 path);
781 return;
782}
783
784
785/**
446 * Add the path to the origin peer and update the path used to reach it in case 786 * Add the path to the origin peer and update the path used to reach it in case
447 * this is the shortest. 787 * this is the shortest.
448 * The path is given in peer_info -> destination, therefore we turn the path 788 * The path is given in peer_info -> destination, therefore we turn the path
@@ -531,6 +871,41 @@ path_build_from_dht (const struct GNUNET_PeerIdentity *const *get_path,
531 871
532 872
533/** 873/**
874 * Send keepalive packets for a peer
875 *
876 * @param cls unused
877 * @param tc unused
878 *
879 * FIXME path
880 */
881void
882path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
883{
884 struct MeshTunnel *t = cls;
885
886// struct GNUNET_PeerIdentity id;
887
888 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
889 {
890 return;
891 }
892 /* FIXME implement multicast keepalive. Just an empty multicast packet? */
893// GNUNET_PEER_resolve (path_get_first_hop (path->t, path->peer)->id, &id);
894// GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
895// GNUNET_TIME_UNIT_FOREVER_REL, &id,
896// sizeof (struct GNUNET_MESH_ManipulatePath)
897// +
898// (path->path->length *
899// sizeof (struct GNUNET_PeerIdentity)),
900// &send_core_create_path,
901// t);
902 t->path_refresh_task =
903 GNUNET_SCHEDULER_add_delayed (t->tree->refresh, &path_refresh, t);
904 return;
905}
906
907
908/**
534 * Check if client has registered with the service and has not disconnected 909 * Check if client has registered with the service and has not disconnected
535 * 910 *
536 * @param client the client to check 911 * @param client the client to check
@@ -628,6 +1003,51 @@ tunnel_get (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid)
628} 1003}
629 1004
630 1005
1006void
1007notify_peer_disconnected (struct MeshTunnelTreeNode *n)
1008{
1009
1010}
1011
1012
1013/**
1014 * Add a peer to a tunnel, accomodating paths accordingly and initializing all
1015 * needed rescources.
1016 *
1017 * @param t Tunnel we want to add a new peer to
1018 * @param peer PeerInfo of the peer being added
1019 *
1020 */
1021void
1022tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer)
1023{
1024 struct MeshPeerPath *p;
1025 struct MeshPeerPath *best_p;
1026 unsigned int best_cost;
1027 unsigned int cost;
1028
1029 GNUNET_array_append (peer->tunnels, peer->ntunnels, t);
1030 if (NULL == (p = peer->path_head))
1031 return;
1032
1033 best_p = p;
1034 best_cost = UINT_MAX;
1035 while (NULL != p)
1036 {
1037 if ((cost = path_get_cost (t->tree, p)) < best_cost)
1038 {
1039 best_cost = cost;
1040 best_p = p;
1041 }
1042 p = p->next;
1043 }
1044 tunnel_add_path (t->tree, best_p, &notify_peer_disconnected);
1045 if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task)
1046 t->path_refresh_task =
1047 GNUNET_SCHEDULER_add_delayed (t->tree->refresh, &path_refresh, t);
1048}
1049
1050
631/** 1051/**
632 * Notify a tunnel that a connection has broken that affects at least 1052 * Notify a tunnel that a connection has broken that affects at least
633 * some of its peers. 1053 * some of its peers.
@@ -656,7 +1076,7 @@ tunnel_notify_connection_broken (struct MeshTunnel *t,
656 * @return GNUNET_OK on success 1076 * @return GNUNET_OK on success
657 */ 1077 */
658static void 1078static void
659tunnel_destroy_tree_node (struct MeshTunnelPathNode *n) 1079tunnel_destroy_tree_node (struct MeshTunnelTreeNode *n)
660{ 1080{
661 unsigned int i; 1081 unsigned int i;
662 1082
@@ -784,7 +1204,7 @@ send_core_create_path (void *cls, size_t size, void *buf)
784 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Retransmitting create path\n"); 1204 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Retransmitting create path\n");
785 GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, 1205 GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
786 GNUNET_TIME_UNIT_FOREVER_REL, 1206 GNUNET_TIME_UNIT_FOREVER_REL,
787 path_get_first_hop (t, peer), 1207 path_get_first_hop (t->tree, peer->id),
788 size_needed, &send_core_create_path, 1208 size_needed, &send_core_create_path,
789 info); 1209 info);
790 return 0; 1210 return 0;
@@ -1310,7 +1730,8 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
1310 memcpy (msg, message, size); 1730 memcpy (msg, message, size);
1311 GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, 1731 GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
1312 GNUNET_TIME_UNIT_FOREVER_REL, 1732 GNUNET_TIME_UNIT_FOREVER_REL,
1313 path_get_first_hop (t, pi), size, 1733 path_get_first_hop (t->tree, pi->id),
1734 size,
1314 &send_core_data_raw, msg); 1735 &send_core_data_raw, msg);
1315 return GNUNET_OK; 1736 return GNUNET_OK;
1316} 1737}
@@ -1537,7 +1958,8 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
1537 memcpy (msg, message, sizeof (struct GNUNET_MESH_PathACK)); 1958 memcpy (msg, message, sizeof (struct GNUNET_MESH_PathACK));
1538 GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, 1959 GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
1539 GNUNET_TIME_UNIT_FOREVER_REL, 1960 GNUNET_TIME_UNIT_FOREVER_REL,
1540 path_get_first_hop (t, peer_info), 1961 path_get_first_hop (t->tree,
1962 peer_info->id),
1541 sizeof (struct GNUNET_MESH_PathACK), 1963 sizeof (struct GNUNET_MESH_PathACK),
1542 &send_core_data_raw, msg); 1964 &send_core_data_raw, msg);
1543 return GNUNET_OK; 1965 return GNUNET_OK;
@@ -1755,7 +2177,7 @@ dht_get_type_handler (void *cls, struct GNUNET_TIME_Absolute exp,
1755 p = path_build_from_dht (get_path, put_path); 2177 p = path_build_from_dht (get_path, put_path);
1756 path_add_to_peer (peer_info, p); 2178 path_add_to_peer (peer_info, p);
1757 tunnel_add_peer(t, peer_info); 2179 tunnel_add_peer(t, peer_info);
1758 p = tunnel_get_path_to_peer(t, peer_info); 2180 p = tunnel_get_path_to_peer(t->tree, peer_info->id);
1759#if MESH_DEBUG 2181#if MESH_DEBUG
1760 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1761 "MESH: new route for tunnel 0x%x found, has %u hops\n", 2183 "MESH: new route for tunnel 0x%x found, has %u hops\n",
@@ -2045,11 +2467,11 @@ handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client,
2045 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 2467 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2046 return; 2468 return;
2047 } 2469 }
2048 t->tree = GNUNET_malloc (sizeof(struct MeshTunnelPath)); 2470 t->tree = GNUNET_malloc (sizeof(struct MeshTunnelTree));
2049 t->tree->first_hops = GNUNET_CONTAINER_multihashmap_create(32); 2471 t->tree->first_hops = GNUNET_CONTAINER_multihashmap_create(32);
2050 t->tree->t = t; 2472 t->tree->t = t;
2051 t->tree->refresh = REFRESH_PATH_TIME; 2473 t->tree->refresh = REFRESH_PATH_TIME;
2052 t->tree->root = GNUNET_malloc(sizeof(struct MeshTunnelPathNode)); 2474 t->tree->root = GNUNET_malloc(sizeof(struct MeshTunnelTreeNode));
2053 t->tree->root->status = MESH_PEER_READY; 2475 t->tree->root->status = MESH_PEER_READY;
2054 t->tree->root->t = t; 2476 t->tree->root->t = t;
2055 t->tree->root->peer = myid; 2477 t->tree->root->peer = myid;
@@ -2428,7 +2850,7 @@ handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client,
2428 info->client = client; 2850 info->client = client;
2429 GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, 2851 GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
2430 GNUNET_TIME_UNIT_FOREVER_REL, 2852 GNUNET_TIME_UNIT_FOREVER_REL,
2431 path_get_first_hop (t, pi), 2853 path_get_first_hop (t->tree, pi->id),
2432 /* FIXME re-check types */ 2854 /* FIXME re-check types */
2433 data_size + 2855 data_size +
2434 sizeof (struct GNUNET_MESH_Unicast), 2856 sizeof (struct GNUNET_MESH_Unicast),
diff --git a/src/mesh/mesh.h b/src/mesh/mesh.h
index 2a7133a55..e816e5ddc 100644
--- a/src/mesh/mesh.h
+++ b/src/mesh/mesh.h
@@ -246,386 +246,5 @@ enum MeshPeerState
246}; 246};
247 247
248 248
249/******************************************************************************/
250/************************ DATA STRUCTURES ****************************/
251/******************************************************************************/
252
253/**
254 * Information regarding a possible path to reach a single peer
255 */
256struct MeshPeerPath
257{
258
259 /**
260 * Linked list
261 */
262 struct MeshPeerPath *next;
263 struct MeshPeerPath *prev;
264
265 /**
266 * List of all the peers that form the path from origin to target.
267 */
268 GNUNET_PEER_Id *peers;
269
270 /**
271 * Number of peers (hops) in the path
272 */
273 unsigned int length;
274
275};
276
277
278/**
279 * Node of path tree for a tunnel
280 */
281struct MeshTunnelPathNode
282{
283 /**
284 * Tunnel this node belongs to (and therefore tree)
285 */
286 struct MeshTunnel *t;
287
288 /**
289 * Peer this node describes
290 */
291 GNUNET_PEER_Id peer;
292
293 /**
294 * Parent node in the tree
295 */
296 struct MeshTunnelPathNode *parent;
297
298 /**
299 * Array of children
300 */
301 struct MeshTunnelPathNode *children;
302
303 /**
304 * Number of children
305 */
306 unsigned int nchildren;
307
308 /**
309 * Status of the peer in the tunnel
310 */
311 enum MeshPeerState status;
312};
313
314
315/**
316 * Tree to reach all peers in the tunnel
317 */
318struct MeshTunnelPath
319{
320 /**
321 * How often to refresh the path
322 */
323 struct GNUNET_TIME_Relative refresh;
324
325 /**
326 * Tunnel this path belongs to
327 */
328 struct MeshTunnel *t;
329
330 /**
331 * Root node of peer tree
332 */
333 struct MeshTunnelPathNode *root;
334
335 /**
336 * Node that represents our position in the tree (for non local tunnels)
337 */
338 struct MeshTunnelPathNode *me;
339
340 /**
341 * Cache of all peers and the first hop to them.
342 * Indexed by Peer_Identity, contains a pointer to the PeerIdentity
343 * of 1st hop.
344 */
345 struct GNUNET_CONTAINER_MultiHashMap *first_hops;
346
347};
348
349
350/** FWD declaration */
351struct MeshPeerInfo;
352
353/**
354 * Struct containing all info possibly needed to build a package when called
355 * back by core.
356 */
357struct MeshDataDescriptor
358{
359 /** ID of the tunnel this packet travels in */
360 struct MESH_TunnelID *origin;
361
362 /** Ultimate destination of the packet */
363 GNUNET_PEER_Id destination;
364
365 /** Number of identical messages sent to different hops (multicast) */
366 unsigned int copies;
367
368 /** Size of the data */
369 size_t size;
370
371 /** Client that asked for the transmission, if any */
372 struct GNUNET_SERVER_Client *client;
373
374 /** Who was is message being sent to */
375 struct MeshPeerInfo *peer;
376
377 /** Which handler was used to request the transmission */
378 unsigned int handler_n;
379
380 /* Data at the end */
381};
382
383
384/**
385 * Struct containing all information regarding a given peer
386 */
387struct MeshPeerInfo
388{
389 /**
390 * ID of the peer
391 */
392 GNUNET_PEER_Id id;
393
394 /**
395 * Last time we heard from this peer
396 */
397 struct GNUNET_TIME_Absolute last_contact;
398
399 /**
400 * Number of attempts to reconnect so far
401 */
402 int n_reconnect_attempts;
403
404 /**
405 * Paths to reach the peer, ordered by ascending hop count
406 */
407 struct MeshPeerPath *path_head;
408
409 /**
410 * Paths to reach the peer, ordered by ascending hop count
411 */
412 struct MeshPeerPath *path_tail;
413
414 /**
415 * Handle to stop the DHT search for a path to this peer
416 */
417 struct GNUNET_DHT_GetHandle *dhtget;
418
419 /**
420 * Handles to stop queued transmissions for this peer
421 */
422 struct GNUNET_CORE_TransmitHandle *core_transmit[CORE_QUEUE_SIZE];
423
424 /**
425 * Pointer to info stuctures used as cls for queued transmissions
426 */
427 struct MeshDataDescriptor *infos[CORE_QUEUE_SIZE];
428
429 /**
430 * Array of tunnels this peer participates in
431 * (most probably a small amount, therefore not a hashmap)
432 * When the path to the peer changes, notify these tunnels to let them
433 * re-adjust their path trees.
434 */
435 struct MeshTunnel **tunnels;
436
437 /**
438 * Number of tunnels above
439 */
440 unsigned int ntunnels;
441};
442
443
444/**
445 * Data scheduled to transmit (to local client or remote peer)
446 */
447struct MeshQueue
448{
449 /**
450 * Double linked list
451 */
452 struct MeshQueue *next;
453 struct MeshQueue *prev;
454
455 /**
456 * Target of the data (NULL if target is client)
457 */
458 struct MeshPeerInfo *peer;
459
460 /**
461 * Client to send the data to (NULL if target is peer)
462 */
463 struct MeshClient *client;
464
465 /**
466 * Size of the message to transmit
467 */
468 unsigned int size;
469
470 /**
471 * How old is the data?
472 */
473 struct GNUNET_TIME_Absolute timestamp;
474
475 /**
476 * Data itself
477 */
478 struct GNUNET_MessageHeader *data;
479};
480
481/**
482 * Globally unique tunnel identification (owner + number)
483 * DO NOT USE OVER THE NETWORK
484 */
485struct MESH_TunnelID
486{
487 /**
488 * Node that owns the tunnel
489 */
490 GNUNET_PEER_Id oid;
491
492 /**
493 * Tunnel number to differentiate all the tunnels owned by the node oid
494 * ( tid < GNUNET_MESH_LOCAL_TUNNEL_ID_CLI )
495 */
496 MESH_TunnelNumber tid;
497};
498
499
500struct MeshClient; /* FWD declaration */
501
502/**
503 * Struct containing all information regarding a tunnel
504 * For an intermediate node the improtant info used will be:
505 * - id Tunnel unique identification
506 * - paths[0] To know where to send it next
507 * - metainfo: ready, speeds, accounting
508 */
509struct MeshTunnel
510{
511 /**
512 * Tunnel ID
513 */
514 struct MESH_TunnelID id;
515
516 /**
517 * Local tunnel number ( >= GNUNET_MESH_LOCAL_TUNNEL_ID_CLI or 0 )
518 */
519 MESH_TunnelNumber local_tid;
520
521 /**
522 * Last time the tunnel was used
523 */
524 struct GNUNET_TIME_Absolute timestamp;
525
526 /**
527 * Peers in the tunnel, indexed by PeerIdentity -> (MeshPeerInfo)
528 */
529 struct GNUNET_CONTAINER_MultiHashMap *peers;
530
531 /**
532 * Number of peers that are connected and potentially ready to receive data
533 */
534 unsigned int peers_ready;
535
536 /**
537 * Number of peers that have been added to the tunnel
538 */
539 unsigned int peers_total;
540
541 /**
542 * Client owner of the tunnel, if any
543 */
544 struct MeshClient *client;
545
546 /**
547 * Messages ready to transmit
548 */
549 struct MeshQueue *queue_head;
550 struct MeshQueue *queue_tail;
551
552 /**
553 * Tunnel paths
554 */
555 struct MeshTunnelPath *tree;
556
557 /**
558 * Task to keep the used paths alive
559 */
560 GNUNET_SCHEDULER_TaskIdentifier path_refresh_task;
561};
562
563
564/**
565 * Info needed to work with tunnel paths and peers
566 */
567struct MeshPathInfo
568{
569 /**
570 * Tunnel
571 */
572 struct MeshTunnel *t;
573
574 /**
575 * Destination peer
576 */
577 struct MeshPeerInfo *peer;
578
579 /**
580 * Path itself
581 */
582 struct MeshPeerPath *path;
583};
584
585
586/**
587 * Struct containing information about a client of the service
588 */
589struct MeshClient
590{
591 /**
592 * Linked list
593 */
594 struct MeshClient *next;
595 struct MeshClient *prev;
596
597 /**
598 * Tunnels that belong to this client, indexed by local id
599 */
600 struct GNUNET_CONTAINER_MultiHashMap *tunnels;
601
602 /**
603 * Handle to communicate with the client
604 */
605 struct GNUNET_SERVER_Client *handle;
606
607 /**
608 * Applications that this client has claimed to provide
609 */
610 struct GNUNET_CONTAINER_MultiHashMap *apps;
611
612 /**
613 * Messages that this client has declared interest in
614 */
615 struct GNUNET_CONTAINER_MultiHashMap *types;
616
617 /**
618 * Used to search peers offering a service
619 */
620 struct GNUNET_DHT_GetHandle *dht_get_type;
621
622#if MESH_DEBUG
623 /**
624 * ID of the client, for debug messages
625 */
626 unsigned int id;
627#endif
628
629};
630 249
631#endif 250#endif
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
31extern GNUNET_PEER_Id myid;
32extern 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 */
81struct GNUNET_PeerIdentity * 77struct GNUNET_PeerIdentity *
82path_get_first_hop (struct MeshTunnel *t, struct MeshPeerInfo *peer) 78path_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 */
120unsigned int 116unsigned int
121path_get_cost (struct MeshTunnel *t, struct MeshPeerPath *path) 117path_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 */
137void
138path_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 */
183void
184path_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 */
219struct MeshTunnelPathNode * 131struct MeshTunnelTreeNode *
220tunnel_find_peer (struct MeshTunnelPathNode *root, GNUNET_PEER_Id peer_id) 132tunnel_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 */
243void 155void
244tunnel_mark_peers_disconnected (struct MeshTunnelPathNode *parent, 156tunnel_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 */
281struct MeshTunnelPathNode * 197struct MeshTunnelTreeNode *
282tunnel_del_path (struct MeshTunnel *t, GNUNET_PEER_Id peer_id, 198tunnel_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 */
325struct MeshPeerPath * 241struct MeshPeerPath *
326tunnel_get_path_to_peer(struct MeshTunnel *t, struct MeshPeerInfo *peer_info) 242tunnel_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 */
367int 282int
368tunnel_add_path (struct MeshTunnel *t, const struct MeshPeerPath *p) 283tunnel_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 */
467void
468tunnel_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}
diff --git a/src/mesh/mesh_tunnel_tree.h b/src/mesh/mesh_tunnel_tree.h
index be4509c9c..fddc9b46d 100644
--- a/src/mesh/mesh_tunnel_tree.h
+++ b/src/mesh/mesh_tunnel_tree.h
@@ -26,6 +26,119 @@
26 26
27#include "mesh.h" 27#include "mesh.h"
28 28
29/******************************************************************************/
30/************************ DATA STRUCTURES ****************************/
31/******************************************************************************/
32
33/**
34 * Information regarding a possible path to reach a single peer
35 */
36struct MeshPeerPath
37{
38
39 /**
40 * Linked list
41 */
42 struct MeshPeerPath *next;
43 struct MeshPeerPath *prev;
44
45 /**
46 * List of all the peers that form the path from origin to target.
47 */
48 GNUNET_PEER_Id *peers;
49
50 /**
51 * Number of peers (hops) in the path
52 */
53 unsigned int length;
54
55};
56
57
58/**
59 * Node of path tree for a tunnel
60 */
61struct MeshTunnelTreeNode
62{
63 /**
64 * Tunnel this node belongs to (and therefore tree)
65 */
66 struct MeshTunnel *t;
67
68 /**
69 * Peer this node describes
70 */
71 GNUNET_PEER_Id peer;
72
73 /**
74 * Parent node in the tree
75 */
76 struct MeshTunnelTreeNode *parent;
77
78 /**
79 * Array of children
80 */
81 struct MeshTunnelTreeNode *children;
82
83 /**
84 * Number of children
85 */
86 unsigned int nchildren;
87
88 /**
89 * Status of the peer in the tunnel
90 */
91 enum MeshPeerState status;
92};
93
94
95/**
96 * Tree to reach all peers in the tunnel
97 */
98struct MeshTunnelTree
99{
100 /**
101 * How often to refresh the path
102 */
103 struct GNUNET_TIME_Relative refresh;
104
105 /**
106 * Tunnel this path belongs to
107 */
108 struct MeshTunnel *t;
109
110 /**
111 * Root node of peer tree
112 */
113 struct MeshTunnelTreeNode *root;
114
115 /**
116 * Node that represents our position in the tree (for non local tunnels)
117 */
118 struct MeshTunnelTreeNode *me;
119
120 /**
121 * Cache of all peers and the first hop to them.
122 * Indexed by Peer_Identity, contains a pointer to the PeerIdentity
123 * of 1st hop.
124 */
125 struct GNUNET_CONTAINER_MultiHashMap *first_hops;
126
127};
128
129
130/******************************************************************************/
131/************************* FUNCTIONS *****************************/
132/******************************************************************************/
133
134
135/**
136 * Method called whenever a node has been marked as disconnected.
137 *
138 * @param node peer identity the tunnel stopped working with
139 */
140typedef void (*MeshNodeDisconnectCB) (const struct MeshTunnelTreeNode * node);
141
29 142
30/** 143/**
31 * Invert the path 144 * Invert the path
@@ -58,7 +171,7 @@ path_destroy (struct MeshPeerPath *p);
58 * NULL on error 171 * NULL on error
59 */ 172 */
60struct GNUNET_PeerIdentity * 173struct GNUNET_PeerIdentity *
61path_get_first_hop (struct MeshTunnel *t, struct MeshPeerInfo *peer); 174path_get_first_hop (struct MeshTunnelTree *t, GNUNET_PEER_Id peer);
62 175
63 176
64/** 177/**
@@ -83,28 +196,7 @@ path_get_length (struct MeshPeerPath *path);
83 * in the path 196 * in the path
84 */ 197 */
85unsigned int 198unsigned int
86path_get_cost (struct MeshTunnel *t, struct MeshPeerPath *path); 199path_get_cost (struct MeshTunnelTree *t, struct MeshPeerPath *path);
87
88/**
89 * Add the path to the peer and update the path used to reach it in case this
90 * is the shortest.
91 *
92 * @param peer_info Destination peer to add the path to.
93 * @param path New path to add. Last peer must be the peer in arg 1.
94 * Path will be either used of freed if already known.
95 */
96void
97path_add_to_peer (struct MeshPeerInfo *peer_info, struct MeshPeerPath *path);
98
99
100/**
101 * Send keepalive packets for a peer
102 *
103 * @param cls unused
104 * @param tc unused
105 */
106void
107path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
108 200
109 201
110/** 202/**
@@ -115,19 +207,19 @@ path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
115 * 207 *
116 * @return Pointer to the node of the peer. NULL if not found. 208 * @return Pointer to the node of the peer. NULL if not found.
117 */ 209 */
118struct MeshTunnelPathNode * 210struct MeshTunnelTreeNode *
119tunnel_find_peer (struct MeshTunnelPathNode *root, GNUNET_PEER_Id peer_id); 211tunnel_find_peer (struct MeshTunnelTreeNode *root, GNUNET_PEER_Id peer_id);
120 212
121 213
122/** 214/**
123 * Recusively mark peer and children as disconnected, notify client 215 * Recusively mark peer and children as disconnected, notify client
124 * 216 *
125 * @param parent Node to be clean, potentially with children 217 * @param parent Node to be clean, potentially with children
126 * @param nc Notification context to use to alert the client 218 * @param cb Callback to use to notify about disconnected peers
127 */ 219 */
128void 220void
129tunnel_mark_peers_disconnected (struct MeshTunnelPathNode *parent, 221tunnel_mark_peers_disconnected (struct MeshTunnelTreeNode *parent,
130 struct GNUNET_SERVER_NotificationContext *nc); 222 MeshNodeDisconnectCB cb);
131 223
132 224
133/** 225/**
@@ -137,13 +229,13 @@ tunnel_mark_peers_disconnected (struct MeshTunnelPathNode *parent,
137 * 229 *
138 * @param t Tunnel where to delete the path from. 230 * @param t Tunnel where to delete the path from.
139 * @param peer Destination peer whose path we want to remove. 231 * @param peer Destination peer whose path we want to remove.
140 * @param nc Notification context to alert the client of disconnected peers. 232 * @param cb Callback to use to notify about disconnected peers
141 * 233 *
142 * @return pointer to the pathless node, NULL on error 234 * @return pointer to the pathless node, NULL on error
143 */ 235 */
144struct MeshTunnelPathNode * 236struct MeshTunnelTreeNode *
145tunnel_del_path (struct MeshTunnel *t, GNUNET_PEER_Id peer_id, 237tunnel_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id,
146 struct GNUNET_SERVER_NotificationContext *nc); 238 MeshNodeDisconnectCB cb);
147 239
148 240
149/** 241/**
@@ -157,7 +249,7 @@ tunnel_del_path (struct MeshTunnel *t, GNUNET_PEER_Id peer_id,
157 * Path must be destroyed afterwards. 249 * Path must be destroyed afterwards.
158 */ 250 */
159struct MeshPeerPath * 251struct MeshPeerPath *
160tunnel_get_path_to_peer(struct MeshTunnel *t, struct MeshPeerInfo *peer_info); 252tunnel_get_path_to_peer(struct MeshTunnelTree *t, GNUNET_PEER_Id peer);
161 253
162 254
163/** 255/**
@@ -165,23 +257,11 @@ tunnel_get_path_to_peer(struct MeshTunnel *t, struct MeshPeerInfo *peer_info);
165 * 257 *
166 * @param t Tunnel where to add the new path. 258 * @param t Tunnel where to add the new path.
167 * @param p Path to be integrated. 259 * @param p Path to be integrated.
168 * @param nc Notification context to alert clients of peers 260 * @param cb Callback to use to notify about peers temporarily disconnecting
169 * temporarily disconnected
170 * 261 *
171 * @return GNUNET_OK in case of success. 262 * @return GNUNET_OK in case of success.
172 * GNUNET_SYSERR in case of error. 263 * GNUNET_SYSERR in case of error.
173 */ 264 */
174int 265int
175tunnel_add_path (struct MeshTunnel *t, const struct MeshPeerPath *p); 266tunnel_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p,
176 267 MeshNodeDisconnectCB cb); \ No newline at end of file
177
178/**
179 * Add a peer to a tunnel, accomodating paths accordingly and initializing all
180 * needed rescources.
181 *
182 * @param t Tunnel we want to add a new peer to
183 * @param peer PeerInfo of the peer being added
184 *
185 */
186void
187tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer); \ No newline at end of file
diff --git a/src/mesh/test_mesh_path_api.c b/src/mesh/test_mesh_path_api.c
index d14d15958..cc0cbc558 100644
--- a/src/mesh/test_mesh_path_api.c
+++ b/src/mesh/test_mesh_path_api.c
@@ -51,7 +51,6 @@ int
51main (int argc, char *argv[]) 51main (int argc, char *argv[])
52{ 52{
53 struct GNUNET_PeerIdentity* pi; 53 struct GNUNET_PeerIdentity* pi;
54// struct MeshTunnel *t;
55 int result; 54 int result;
56 55
57 GNUNET_log_setup ("test_mesh_api_path", 56 GNUNET_log_setup ("test_mesh_api_path",
@@ -61,6 +60,7 @@ main (int argc, char *argv[])
61 "WARNING", 60 "WARNING",
62#endif 61#endif
63 NULL); 62 NULL);
63
64 pi = get_pi(1); 64 pi = get_pi(1);
65 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Peer 1: %s\n", GNUNET_h2s(&pi->hashPubKey)); 65 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Peer 1: %s\n", GNUNET_h2s(&pi->hashPubKey));
66 66