2 This file is part of GNUnet.
3 Copyright (C) 2017 GNUnet e.V.
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
22 * @file cadet/gnunet-service-cadet_core.c
23 * @brief cadet service; interaction with CORE service
24 * @author Bartlomiej Polot
25 * @author Christian Grothoff
27 * All functions in this file should use the prefix GCO (Gnunet Cadet cOre (bottom))
30 #include "gnunet-service-cadet-new_core.h"
31 #include "gnunet-service-cadet-new_paths.h"
32 #include "gnunet-service-cadet-new_peer.h"
33 #include "gnunet-service-cadet-new_connection.h"
34 #include "gnunet_core_service.h"
35 #include "cadet_protocol.h"
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
50 * Previous hop on this route.
52 struct CadetPeer *prev_hop;
55 * Next hop on this route.
57 struct CadetPeer *next_hop;
60 * Unique identifier for the connection that uses this route.
62 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
65 * When was this route last in use?
67 struct GNUNET_TIME_Absolute last_use;
73 * Handle to the CORE service.
75 static struct GNUNET_CORE_Handle *core;
78 * Routes on which this peer is an intermediate.
80 static struct GNUNET_CONTAINER_MultiShortmap *routes;
84 * Get the route corresponding to a hash.
86 * @param cid hash generated from the connection identifier
88 static struct CadetRoute *
89 get_route (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
91 return GNUNET_CONTAINER_multishortmap_get (routes,
92 &cid->connection_of_tunnel);
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
101 * @param prev previous hop (sender)
102 * @param cid connection identifier, tells us which route to use
103 * @param msg the message to forward
106 route_message (struct CadetPeer *prev,
107 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
108 const struct GNUNET_MessageHeader *msg)
110 struct CadetRoute *route;
112 route = get_route (cid);
115 struct GNUNET_MQ_Envelope *env;
116 struct GNUNET_CADET_ConnectionBroken *bm;
118 env = GNUNET_MQ_msg (bm,
119 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
121 bm->peer1 = my_full_id;
126 GNUNET_assert (0); /* FIXME: determine next hop from route and prev! */
132 * Check if the create_connection message has the appropriate size.
134 * @param cls Closure (unused).
135 * @param msg Message to check.
137 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
140 check_create (void *cls,
141 const struct GNUNET_CADET_ConnectionCreate *msg)
143 uint16_t size = ntohs (msg->header.size) - sizeof (*msg);
145 if (0 != (size % sizeof (struct GNUNET_PeerIdentity)))
155 * Destroy our state for @a route.
157 * @param route route to destroy
160 destroy_route (struct CadetRoute *route)
162 GNUNET_break (0); // fIXME: implement!
167 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE
169 * @param cls Closure (CadetPeer for neighbor that sent the message).
170 * @param msg Message itself.
173 handle_create (void *cls,
174 const struct GNUNET_CADET_ConnectionCreate *msg)
176 struct CadetPeer *peer = cls;
177 uint16_t size = ntohs (msg->header.size) - sizeof (*msg);
178 unsigned int path_length;
180 path_length = size / sizeof (struct GNUNET_PeerIdentity);
182 GCC_handle_create (peer,
185 (const struct GNUNET_PeerIdentity *) &msg[1]);
191 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK
193 * @param cls Closure (CadetPeer for neighbor that sent the message).
194 * @param msg Message itself.
197 handle_connection_ack (void *cls,
198 const struct GNUNET_CADET_ConnectionACK *msg)
200 struct CadetPeer *peer = cls;
201 struct CadetConnection *cc;
203 /* First, check if ACK belongs to a connection that ends here. */
204 cc = GNUNET_CONTAINER_multishortmap_get (connections,
205 &msg->cid.connection_of_tunnel);
208 /* verify ACK came from the right direction */
209 struct CadetPeerPath *path = GCC_get_path (cc);
212 GCPP_get_peer_at_offset (path,
215 /* received ACK from unexpected direction, ignore! */
219 GCC_handle_connection_ack (cc);
223 /* We're just an intermediary peer, route the message along its path */
231 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
233 * @param cls Closure (CadetPeer for neighbor that sent the message).
234 * @param msg Message itself.
235 * @deprecated duplicate logic with #handle_destroy(); dedup!
238 handle_broken (void *cls,
239 const struct GNUNET_CADET_ConnectionBroken *msg)
241 struct CadetPeer *peer = cls;
242 struct CadetConnection *cc;
243 struct CadetRoute *route;
245 /* First, check if message belongs to a connection that ends here. */
246 cc = GNUNET_CONTAINER_multishortmap_get (connections,
247 &msg->cid.connection_of_tunnel);
250 /* verify message came from the right direction */
251 struct CadetPeerPath *path = GCC_get_path (cc);
254 GCPP_get_peer_at_offset (path,
257 /* received message from unexpected direction, ignore! */
265 /* We're just an intermediary peer, route the message along its path */
266 route = get_route (&msg->cid);
270 destroy_route (route);
275 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY
277 * @param cls Closure (CadetPeer for neighbor that sent the message).
278 * @param msg Message itself.
281 handle_destroy (void *cls,
282 const struct GNUNET_CADET_ConnectionDestroy *msg)
284 struct CadetPeer *peer = cls;
285 struct CadetConnection *cc;
286 struct CadetRoute *route;
288 /* First, check if message belongs to a connection that ends here. */
289 cc = GNUNET_CONTAINER_multishortmap_get (connections,
290 &msg->cid.connection_of_tunnel);
293 /* verify message came from the right direction */
294 struct CadetPeerPath *path = GCC_get_path (cc);
297 GCPP_get_peer_at_offset (path,
300 /* received message from unexpected direction, ignore! */
308 /* We're just an intermediary peer, route the message along its path */
309 route = get_route (&msg->cid);
313 destroy_route (route);
318 * Handle for #GNUNET_MESSAGE_TYPE_CADET_ACK
320 * @param cls Closure (CadetPeer for neighbor that sent the message).
321 * @param msg Message itself.
324 handle_ack (void *cls,
325 const struct GNUNET_CADET_ACK *msg)
327 struct CadetPeer *peer = cls;
330 GCC_handle_ack (peer,
337 * Handle for #GNUNET_MESSAGE_TYPE_CADET_POLL
339 * @param cls Closure (CadetPeer for neighbor that sent the message).
340 * @param msg Message itself.
343 handle_poll (void *cls,
344 const struct GNUNET_CADET_Poll *msg)
346 struct CadetPeer *peer = cls;
349 GCC_handle_poll (peer,
356 * Handle for #GNUNET_MESSAGE_TYPE_CADET_KX
358 * @param cls Closure (CadetPeer for neighbor that sent the message).
359 * @param msg Message itself.
362 handle_kx (void *cls,
363 const struct GNUNET_CADET_KX *msg)
365 struct CadetPeer *peer = cls;
366 struct CadetConnection *cc;
368 /* First, check if message belongs to a connection that ends here. */
369 cc = GNUNET_CONTAINER_multishortmap_get (connections,
370 &msg->cid.connection_of_tunnel);
373 /* verify message came from the right direction */
374 struct CadetPeerPath *path = GCC_get_path (cc);
377 GCPP_get_peer_at_offset (path,
380 /* received message from unexpected direction, ignore! */
389 /* We're just an intermediary peer, route the message along its path */
397 * Check if the encrypted message has the appropriate size.
399 * @param cls Closure (unused).
400 * @param msg Message to check.
402 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
405 check_encrypted (void *cls,
406 const struct GNUNET_CADET_Encrypted *msg)
413 * Handle for #GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED.
415 * @param cls Closure (CadetPeer for neighbor that sent the message).
416 * @param msg Message itself.
419 handle_encrypted (void *cls,
420 const struct GNUNET_CADET_Encrypted *msg)
422 struct CadetPeer *peer = cls;
423 struct CadetConnection *cc;
425 /* First, check if message belongs to a connection that ends here. */
426 cc = GNUNET_CONTAINER_multishortmap_get (connections,
427 &msg->cid.connection_of_tunnel);
430 /* verify message came from the right direction */
431 struct CadetPeerPath *path = GCC_get_path (cc);
434 GCPP_get_peer_at_offset (path,
437 /* received message from unexpected direction, ignore! */
441 GCC_handle_encrypted (cc,
446 /* We're just an intermediary peer, route the message along its path */
454 * Function called after #GNUNET_CORE_connect has succeeded (or failed
455 * for good). Note that the private key of the peer is intentionally
456 * not exposed here; if you need it, your process should try to read
457 * the private key file directly (which should work if you are
458 * authorized...). Implementations of this function must not call
459 * #GNUNET_CORE_disconnect (other than by scheduling a new task to
463 * @param my_identity ID of this peer, NULL if we failed
466 core_init_cb (void *cls,
467 const struct GNUNET_PeerIdentity *my_identity)
469 if (NULL == my_identity)
477 sizeof (struct GNUNET_PeerIdentity)));
482 * Method called whenever a given peer connects.
485 * @param peer peer identity this notification is about
488 core_connect_cb (void *cls,
489 const struct GNUNET_PeerIdentity *peer,
490 struct GNUNET_MQ_Handle *mq)
492 struct CadetPeer *cp;
503 * Method called whenever a peer disconnects.
506 * @param peer peer identity this notification is about
509 core_disconnect_cb (void *cls,
510 const struct GNUNET_PeerIdentity *peer,
513 struct CadetPeer *cp = peer_cls;
515 /* FIXME: also check all routes going via peer and
516 send broken messages to the other direction! */
524 * Initialize the CORE subsystem.
526 * @param c Configuration.
529 GCO_init (const struct GNUNET_CONFIGURATION_Handle *c)
531 struct GNUNET_MQ_MessageHandler handlers[] = {
532 GNUNET_MQ_hd_var_size (create,
533 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE,
534 struct GNUNET_CADET_ConnectionCreate,
536 GNUNET_MQ_hd_fixed_size (connection_ack,
537 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK,
538 struct GNUNET_CADET_ConnectionACK,
540 GNUNET_MQ_hd_fixed_size (broken,
541 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN,
542 struct GNUNET_CADET_ConnectionBroken,
544 GNUNET_MQ_hd_fixed_size (destroy,
545 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY,
546 struct GNUNET_CADET_ConnectionDestroy,
548 GNUNET_MQ_hd_fixed_size (ack,
549 GNUNET_MESSAGE_TYPE_CADET_ACK,
550 struct GNUNET_CADET_ACK,
552 GNUNET_MQ_hd_fixed_size (poll,
553 GNUNET_MESSAGE_TYPE_CADET_POLL,
554 struct GNUNET_CADET_Poll,
556 GNUNET_MQ_hd_fixed_size (kx,
557 GNUNET_MESSAGE_TYPE_CADET_KX,
558 struct GNUNET_CADET_KX,
560 GNUNET_MQ_hd_var_size (encrypted,
561 GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED,
562 struct GNUNET_CADET_Encrypted,
564 GNUNET_MQ_handler_end ()
567 routes = GNUNET_CONTAINER_multishortmap_create (1024,
569 core = GNUNET_CORE_connect (c,
579 * Shut down the CORE subsystem.
586 GNUNET_CORE_disconnect (core);
589 GNUNET_assert (0 == GNUNET_CONTAINER_multishortmap_size (routes));
590 GNUNET_CONTAINER_multishortmap_destroy (routes);
593 /* end of gnunet-cadet-service_core.c */