aboutsummaryrefslogtreecommitdiff
path: root/src/mesh/gnunet-service-mesh.c
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-09-20 17:22:58 +0000
committerBart Polot <bart@net.in.tum.de>2011-09-20 17:22:58 +0000
commit62cf5f2f6da72d38adac69e239400edd501ef9cb (patch)
treed60c7b9e70328628d81ad2176a5cc9f96c441c37 /src/mesh/gnunet-service-mesh.c
parent73e047c74d351257f8b6cf0815a56ff650520cc1 (diff)
downloadgnunet-62cf5f2f6da72d38adac69e239400edd501ef9cb.tar.gz
gnunet-62cf5f2f6da72d38adac69e239400edd501ef9cb.zip
Cleaned and fixed refactoring to improve separation, only 3 structs are now shared
Diffstat (limited to 'src/mesh/gnunet-service-mesh.c')
-rw-r--r--src/mesh/gnunet-service-mesh.c440
1 files changed, 431 insertions, 9 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),