diff options
Diffstat (limited to 'src/cadet/gnunet-service-cadet-new_core.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet-new_core.c | 460 |
1 files changed, 460 insertions, 0 deletions
diff --git a/src/cadet/gnunet-service-cadet-new_core.c b/src/cadet/gnunet-service-cadet-new_core.c index a24f7a3ce..8cc6c843e 100644 --- a/src/cadet/gnunet-service-cadet-new_core.c +++ b/src/cadet/gnunet-service-cadet-new_core.c | |||
@@ -28,15 +28,435 @@ | |||
28 | */ | 28 | */ |
29 | #include "platform.h" | 29 | #include "platform.h" |
30 | #include "gnunet-service-cadet-new_core.h" | 30 | #include "gnunet-service-cadet-new_core.h" |
31 | #include "gnunet-service-cadet-new_paths.h" | ||
31 | #include "gnunet-service-cadet-new_peer.h" | 32 | #include "gnunet-service-cadet-new_peer.h" |
32 | #include "gnunet-service-cadet-new_connection.h" | 33 | #include "gnunet-service-cadet-new_connection.h" |
33 | #include "gnunet_core_service.h" | 34 | #include "gnunet_core_service.h" |
35 | #include "cadet_protocol.h" | ||
36 | |||
37 | |||
38 | /** | ||
39 | * Description of a segment of a `struct CadetConnection` at the | ||
40 | * intermediate peers. Routes are basically entries in a peer's | ||
41 | * routing table for forwarding traffic. At both endpoints, the | ||
42 | * routes are terminated by a `struct CadetConnection`, which knows | ||
43 | * the complete `struct CadetPath` that is formed by the individual | ||
44 | * routes. | ||
45 | */ | ||
46 | struct CadetRoute | ||
47 | { | ||
48 | |||
49 | /** | ||
50 | * Previous hop on this route. | ||
51 | */ | ||
52 | struct CadetPeer *prev_hop; | ||
53 | |||
54 | /** | ||
55 | * Next hop on this route. | ||
56 | */ | ||
57 | struct CadetPeer *next_hop; | ||
58 | |||
59 | /** | ||
60 | * Unique identifier for the connection that uses this route. | ||
61 | */ | ||
62 | struct GNUNET_CADET_ConnectionTunnelIdentifier cid; | ||
63 | |||
64 | /** | ||
65 | * When was this route last in use? | ||
66 | */ | ||
67 | struct GNUNET_TIME_Absolute last_use; | ||
68 | |||
69 | }; | ||
70 | |||
34 | 71 | ||
35 | /** | 72 | /** |
36 | * Handle to the CORE service. | 73 | * Handle to the CORE service. |
37 | */ | 74 | */ |
38 | static struct GNUNET_CORE_Handle *core; | 75 | static struct GNUNET_CORE_Handle *core; |
39 | 76 | ||
77 | /** | ||
78 | * Routes on which this peer is an intermediate. | ||
79 | */ | ||
80 | static struct GNUNET_CONTAINER_MultiHashMap *routes; | ||
81 | |||
82 | |||
83 | /** | ||
84 | * Get the route corresponding to a hash. | ||
85 | * | ||
86 | * @param cid hash generated from the connection identifier | ||
87 | */ | ||
88 | static struct CadetRoute * | ||
89 | get_route (const struct GNUNET_HashCode *cid) | ||
90 | { | ||
91 | return GNUNET_CONTAINER_multihashmap_get (routes, | ||
92 | cid); | ||
93 | } | ||
94 | |||
95 | |||
96 | /** | ||
97 | * We message @a msg from @a prev. Find its route by @a cid and | ||
98 | * forward to the next hop. Drop and signal broken route if we do not | ||
99 | * have a route. | ||
100 | * | ||
101 | * @param prev previous hop (sender) | ||
102 | * @param cid connection identifier, tells us which route to use | ||
103 | * @param msg the message to forward | ||
104 | */ | ||
105 | static void | ||
106 | route_message (struct CadetPeer *prev, | ||
107 | const struct GNUNET_HashCode *cid, /* FIXME: bad type... */ | ||
108 | const struct GNUNET_MessageHeader *msg) | ||
109 | { | ||
110 | struct CadetRoute *route; | ||
111 | |||
112 | route = get_route (cid); | ||
113 | if (NULL == route) | ||
114 | { | ||
115 | struct GNUNET_MQ_Envelope *env; | ||
116 | struct GNUNET_CADET_ConnectionBroken *bm; | ||
117 | |||
118 | env = GNUNET_MQ_msg (bm, | ||
119 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); | ||
120 | /* FIXME: ugly */ | ||
121 | memcpy (&bm->cid, | ||
122 | cid, | ||
123 | sizeof (bm->cid)); | ||
124 | bm->peer1 = my_full_id; | ||
125 | GCP_send (prev, | ||
126 | env); | ||
127 | return; | ||
128 | } | ||
129 | GNUNET_assert (0); /* FIXME: determine next hop from route and prev! */ | ||
130 | |||
131 | } | ||
132 | |||
133 | |||
134 | /** | ||
135 | * Check if the create_connection message has the appropriate size. | ||
136 | * | ||
137 | * @param cls Closure (unused). | ||
138 | * @param msg Message to check. | ||
139 | * | ||
140 | * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise. | ||
141 | */ | ||
142 | static int | ||
143 | check_create (void *cls, | ||
144 | const struct GNUNET_CADET_ConnectionCreate *msg) | ||
145 | { | ||
146 | uint16_t size = ntohs (msg->header.size) - sizeof (*msg); | ||
147 | |||
148 | if (0 != (size % sizeof (struct GNUNET_PeerIdentity))) | ||
149 | { | ||
150 | GNUNET_break_op (0); | ||
151 | return GNUNET_NO; | ||
152 | } | ||
153 | return GNUNET_YES; | ||
154 | } | ||
155 | |||
156 | |||
157 | /** | ||
158 | * Destroy our state for @a route. | ||
159 | * | ||
160 | * @param route route to destroy | ||
161 | */ | ||
162 | static void | ||
163 | destroy_route (struct CadetRoute *route) | ||
164 | { | ||
165 | GNUNET_break (0); // fIXME: implement! | ||
166 | } | ||
167 | |||
168 | |||
169 | /** | ||
170 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE | ||
171 | * | ||
172 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
173 | * @param msg Message itself. | ||
174 | */ | ||
175 | static void | ||
176 | handle_create (void *cls, | ||
177 | const struct GNUNET_CADET_ConnectionCreate *msg) | ||
178 | { | ||
179 | struct CadetPeer *peer = cls; | ||
180 | uint16_t size = ntohs (msg->header.size) - sizeof (*msg); | ||
181 | unsigned int path_length; | ||
182 | |||
183 | path_length = size / sizeof (struct GNUNET_PeerIdentity); | ||
184 | #if FIXME | ||
185 | GCC_handle_create (peer, | ||
186 | &msg->cid, | ||
187 | path_length, | ||
188 | (const struct GNUNET_PeerIdentity *) &msg[1]); | ||
189 | #endif | ||
190 | } | ||
191 | |||
192 | |||
193 | /** | ||
194 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK | ||
195 | * | ||
196 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
197 | * @param msg Message itself. | ||
198 | */ | ||
199 | static void | ||
200 | handle_connection_ack (void *cls, | ||
201 | const struct GNUNET_CADET_ConnectionACK *msg) | ||
202 | { | ||
203 | struct CadetPeer *peer = cls; | ||
204 | const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel); | ||
205 | struct CadetConnection *cc; | ||
206 | |||
207 | /* First, check if ACK belongs to a connection that ends here. */ | ||
208 | cc = GNUNET_CONTAINER_multihashmap_get (connections, | ||
209 | cid); | ||
210 | if (NULL != cc) | ||
211 | { | ||
212 | /* verify ACK came from the right direction */ | ||
213 | struct CadetPeerPath *path = GCC_get_path (cc); | ||
214 | |||
215 | if (peer != | ||
216 | GCPP_get_peer_at_offset (path, | ||
217 | 0)) | ||
218 | { | ||
219 | /* received ACK from unexpected direction, ignore! */ | ||
220 | GNUNET_break_op (0); | ||
221 | return; | ||
222 | } | ||
223 | GCC_handle_connection_ack (cc); | ||
224 | return; | ||
225 | } | ||
226 | |||
227 | /* We're just an intermediary peer, route the message along its path */ | ||
228 | route_message (peer, | ||
229 | cid, | ||
230 | &msg->header); | ||
231 | } | ||
232 | |||
233 | |||
234 | /** | ||
235 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN | ||
236 | * | ||
237 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
238 | * @param msg Message itself. | ||
239 | * @deprecated duplicate logic with #handle_destroy(); dedup! | ||
240 | */ | ||
241 | static void | ||
242 | handle_broken (void *cls, | ||
243 | const struct GNUNET_CADET_ConnectionBroken *msg) | ||
244 | { | ||
245 | struct CadetPeer *peer = cls; | ||
246 | const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel); | ||
247 | struct CadetConnection *cc; | ||
248 | struct CadetRoute *route; | ||
249 | |||
250 | /* First, check if message belongs to a connection that ends here. */ | ||
251 | cc = GNUNET_CONTAINER_multihashmap_get (connections, | ||
252 | cid); | ||
253 | if (NULL != cc) | ||
254 | { | ||
255 | /* verify message came from the right direction */ | ||
256 | struct CadetPeerPath *path = GCC_get_path (cc); | ||
257 | |||
258 | if (peer != | ||
259 | GCPP_get_peer_at_offset (path, | ||
260 | 0)) | ||
261 | { | ||
262 | /* received message from unexpected direction, ignore! */ | ||
263 | GNUNET_break_op (0); | ||
264 | return; | ||
265 | } | ||
266 | GCC_destroy (cc); | ||
267 | return; | ||
268 | } | ||
269 | |||
270 | /* We're just an intermediary peer, route the message along its path */ | ||
271 | route = get_route (cid); | ||
272 | route_message (peer, | ||
273 | cid, | ||
274 | &msg->header); | ||
275 | destroy_route (route); | ||
276 | } | ||
277 | |||
278 | |||
279 | /** | ||
280 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY | ||
281 | * | ||
282 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
283 | * @param msg Message itself. | ||
284 | */ | ||
285 | static void | ||
286 | handle_destroy (void *cls, | ||
287 | const struct GNUNET_CADET_ConnectionDestroy *msg) | ||
288 | { | ||
289 | struct CadetPeer *peer = cls; | ||
290 | const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel); | ||
291 | struct CadetConnection *cc; | ||
292 | struct CadetRoute *route; | ||
293 | |||
294 | /* First, check if message belongs to a connection that ends here. */ | ||
295 | cc = GNUNET_CONTAINER_multihashmap_get (connections, | ||
296 | cid); | ||
297 | if (NULL != cc) | ||
298 | { | ||
299 | /* verify message came from the right direction */ | ||
300 | struct CadetPeerPath *path = GCC_get_path (cc); | ||
301 | |||
302 | if (peer != | ||
303 | GCPP_get_peer_at_offset (path, | ||
304 | 0)) | ||
305 | { | ||
306 | /* received message from unexpected direction, ignore! */ | ||
307 | GNUNET_break_op (0); | ||
308 | return; | ||
309 | } | ||
310 | GCC_destroy (cc); | ||
311 | return; | ||
312 | } | ||
313 | |||
314 | /* We're just an intermediary peer, route the message along its path */ | ||
315 | route = get_route (cid); | ||
316 | route_message (peer, | ||
317 | cid, | ||
318 | &msg->header); | ||
319 | destroy_route (route); | ||
320 | } | ||
321 | |||
322 | |||
323 | /** | ||
324 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_ACK | ||
325 | * | ||
326 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
327 | * @param msg Message itself. | ||
328 | */ | ||
329 | static void | ||
330 | handle_ack (void *cls, | ||
331 | const struct GNUNET_CADET_ACK *msg) | ||
332 | { | ||
333 | struct CadetPeer *peer = cls; | ||
334 | |||
335 | #if FIXME | ||
336 | GCC_handle_ack (peer, | ||
337 | msg); | ||
338 | #endif | ||
339 | } | ||
340 | |||
341 | |||
342 | /** | ||
343 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_POLL | ||
344 | * | ||
345 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
346 | * @param msg Message itself. | ||
347 | */ | ||
348 | static void | ||
349 | handle_poll (void *cls, | ||
350 | const struct GNUNET_CADET_Poll *msg) | ||
351 | { | ||
352 | struct CadetPeer *peer = cls; | ||
353 | |||
354 | #if FIXME | ||
355 | GCC_handle_poll (peer, | ||
356 | msg); | ||
357 | #endif | ||
358 | } | ||
359 | |||
360 | |||
361 | /** | ||
362 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_KX | ||
363 | * | ||
364 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
365 | * @param msg Message itself. | ||
366 | */ | ||
367 | static void | ||
368 | handle_kx (void *cls, | ||
369 | const struct GNUNET_CADET_KX *msg) | ||
370 | { | ||
371 | struct CadetPeer *peer = cls; | ||
372 | const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel); | ||
373 | struct CadetConnection *cc; | ||
374 | |||
375 | /* First, check if message belongs to a connection that ends here. */ | ||
376 | cc = GNUNET_CONTAINER_multihashmap_get (connections, | ||
377 | cid); | ||
378 | if (NULL != cc) | ||
379 | { | ||
380 | /* verify message came from the right direction */ | ||
381 | struct CadetPeerPath *path = GCC_get_path (cc); | ||
382 | |||
383 | if (peer != | ||
384 | GCPP_get_peer_at_offset (path, | ||
385 | 0)) | ||
386 | { | ||
387 | /* received message from unexpected direction, ignore! */ | ||
388 | GNUNET_break_op (0); | ||
389 | return; | ||
390 | } | ||
391 | GCC_handle_kx (cc, | ||
392 | msg); | ||
393 | return; | ||
394 | } | ||
395 | |||
396 | /* We're just an intermediary peer, route the message along its path */ | ||
397 | route_message (peer, | ||
398 | cid, | ||
399 | &msg->header); | ||
400 | } | ||
401 | |||
402 | |||
403 | /** | ||
404 | * Check if the encrypted message has the appropriate size. | ||
405 | * | ||
406 | * @param cls Closure (unused). | ||
407 | * @param msg Message to check. | ||
408 | * | ||
409 | * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise. | ||
410 | */ | ||
411 | static int | ||
412 | check_encrypted (void *cls, | ||
413 | const struct GNUNET_CADET_Encrypted *msg) | ||
414 | { | ||
415 | return GNUNET_YES; | ||
416 | } | ||
417 | |||
418 | |||
419 | /** | ||
420 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED. | ||
421 | * | ||
422 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
423 | * @param msg Message itself. | ||
424 | */ | ||
425 | static void | ||
426 | handle_encrypted (void *cls, | ||
427 | const struct GNUNET_CADET_Encrypted *msg) | ||
428 | { | ||
429 | struct CadetPeer *peer = cls; | ||
430 | const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel); | ||
431 | struct CadetConnection *cc; | ||
432 | |||
433 | /* First, check if message belongs to a connection that ends here. */ | ||
434 | cc = GNUNET_CONTAINER_multihashmap_get (connections, | ||
435 | cid); | ||
436 | if (NULL != cc) | ||
437 | { | ||
438 | /* verify message came from the right direction */ | ||
439 | struct CadetPeerPath *path = GCC_get_path (cc); | ||
440 | |||
441 | if (peer != | ||
442 | GCPP_get_peer_at_offset (path, | ||
443 | 0)) | ||
444 | { | ||
445 | /* received message from unexpected direction, ignore! */ | ||
446 | GNUNET_break_op (0); | ||
447 | return; | ||
448 | } | ||
449 | GCC_handle_encrypted (cc, | ||
450 | msg); | ||
451 | return; | ||
452 | } | ||
453 | |||
454 | /* We're just an intermediary peer, route the message along its path */ | ||
455 | route_message (peer, | ||
456 | cid, | ||
457 | &msg->header); | ||
458 | } | ||
459 | |||
40 | 460 | ||
41 | /** | 461 | /** |
42 | * Function called after #GNUNET_CORE_connect has succeeded (or failed | 462 | * Function called after #GNUNET_CORE_connect has succeeded (or failed |
@@ -100,6 +520,9 @@ core_disconnect_cb (void *cls, | |||
100 | { | 520 | { |
101 | struct CadetPeer *cp = peer_cls; | 521 | struct CadetPeer *cp = peer_cls; |
102 | 522 | ||
523 | /* FIXME: also check all routes going via peer and | ||
524 | send broken messages to the other direction! */ | ||
525 | GNUNET_break (0); | ||
103 | GCP_set_mq (cp, | 526 | GCP_set_mq (cp, |
104 | NULL); | 527 | NULL); |
105 | } | 528 | } |
@@ -114,8 +537,43 @@ void | |||
114 | GCO_init (const struct GNUNET_CONFIGURATION_Handle *c) | 537 | GCO_init (const struct GNUNET_CONFIGURATION_Handle *c) |
115 | { | 538 | { |
116 | struct GNUNET_MQ_MessageHandler handlers[] = { | 539 | struct GNUNET_MQ_MessageHandler handlers[] = { |
540 | GNUNET_MQ_hd_var_size (create, | ||
541 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE, | ||
542 | struct GNUNET_CADET_ConnectionCreate, | ||
543 | NULL), | ||
544 | GNUNET_MQ_hd_fixed_size (connection_ack, | ||
545 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK, | ||
546 | struct GNUNET_CADET_ConnectionACK, | ||
547 | NULL), | ||
548 | GNUNET_MQ_hd_fixed_size (broken, | ||
549 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN, | ||
550 | struct GNUNET_CADET_ConnectionBroken, | ||
551 | NULL), | ||
552 | GNUNET_MQ_hd_fixed_size (destroy, | ||
553 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY, | ||
554 | struct GNUNET_CADET_ConnectionDestroy, | ||
555 | NULL), | ||
556 | GNUNET_MQ_hd_fixed_size (ack, | ||
557 | GNUNET_MESSAGE_TYPE_CADET_ACK, | ||
558 | struct GNUNET_CADET_ACK, | ||
559 | NULL), | ||
560 | GNUNET_MQ_hd_fixed_size (poll, | ||
561 | GNUNET_MESSAGE_TYPE_CADET_POLL, | ||
562 | struct GNUNET_CADET_Poll, | ||
563 | NULL), | ||
564 | GNUNET_MQ_hd_fixed_size (kx, | ||
565 | GNUNET_MESSAGE_TYPE_CADET_KX, | ||
566 | struct GNUNET_CADET_KX, | ||
567 | NULL), | ||
568 | GNUNET_MQ_hd_var_size (encrypted, | ||
569 | GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED, | ||
570 | struct GNUNET_CADET_Encrypted, | ||
571 | NULL), | ||
117 | GNUNET_MQ_handler_end () | 572 | GNUNET_MQ_handler_end () |
118 | }; | 573 | }; |
574 | |||
575 | routes = GNUNET_CONTAINER_multihashmap_create (1024, | ||
576 | GNUNET_NO); | ||
119 | core = GNUNET_CORE_connect (c, | 577 | core = GNUNET_CORE_connect (c, |
120 | NULL, | 578 | NULL, |
121 | &core_init_cb, | 579 | &core_init_cb, |
@@ -136,6 +594,8 @@ GCO_shutdown () | |||
136 | GNUNET_CORE_disconnect (core); | 594 | GNUNET_CORE_disconnect (core); |
137 | core = NULL; | 595 | core = NULL; |
138 | } | 596 | } |
597 | GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (routes)); | ||
598 | GNUNET_CONTAINER_multihashmap_destroy (routes); | ||
139 | } | 599 | } |
140 | 600 | ||
141 | /* end of gnunet-cadet-service_core.c */ | 601 | /* end of gnunet-cadet-service_core.c */ |