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_MultiHashMap *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_HashCode *cid)
91 return GNUNET_CONTAINER_multihashmap_get (routes,
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_HashCode *cid, /* FIXME: bad type... */
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);
124 bm->peer1 = my_full_id;
129 GNUNET_assert (0); /* FIXME: determine next hop from route and prev! */
135 * Check if the create_connection message has the appropriate size.
137 * @param cls Closure (unused).
138 * @param msg Message to check.
140 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
143 check_create (void *cls,
144 const struct GNUNET_CADET_ConnectionCreate *msg)
146 uint16_t size = ntohs (msg->header.size) - sizeof (*msg);
148 if (0 != (size % sizeof (struct GNUNET_PeerIdentity)))
158 * Destroy our state for @a route.
160 * @param route route to destroy
163 destroy_route (struct CadetRoute *route)
165 GNUNET_break (0); // fIXME: implement!
170 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE
172 * @param cls Closure (CadetPeer for neighbor that sent the message).
173 * @param msg Message itself.
176 handle_create (void *cls,
177 const struct GNUNET_CADET_ConnectionCreate *msg)
179 struct CadetPeer *peer = cls;
180 uint16_t size = ntohs (msg->header.size) - sizeof (*msg);
181 unsigned int path_length;
183 path_length = size / sizeof (struct GNUNET_PeerIdentity);
185 GCC_handle_create (peer,
188 (const struct GNUNET_PeerIdentity *) &msg[1]);
194 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK
196 * @param cls Closure (CadetPeer for neighbor that sent the message).
197 * @param msg Message itself.
200 handle_connection_ack (void *cls,
201 const struct GNUNET_CADET_ConnectionACK *msg)
203 struct CadetPeer *peer = cls;
204 const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel);
205 struct CadetConnection *cc;
207 /* First, check if ACK belongs to a connection that ends here. */
208 cc = GNUNET_CONTAINER_multihashmap_get (connections,
212 /* verify ACK came from the right direction */
213 struct CadetPeerPath *path = GCC_get_path (cc);
216 GCPP_get_peer_at_offset (path,
219 /* received ACK from unexpected direction, ignore! */
223 GCC_handle_connection_ack (cc);
227 /* We're just an intermediary peer, route the message along its path */
235 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
237 * @param cls Closure (CadetPeer for neighbor that sent the message).
238 * @param msg Message itself.
239 * @deprecated duplicate logic with #handle_destroy(); dedup!
242 handle_broken (void *cls,
243 const struct GNUNET_CADET_ConnectionBroken *msg)
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;
250 /* First, check if message belongs to a connection that ends here. */
251 cc = GNUNET_CONTAINER_multihashmap_get (connections,
255 /* verify message came from the right direction */
256 struct CadetPeerPath *path = GCC_get_path (cc);
259 GCPP_get_peer_at_offset (path,
262 /* received message from unexpected direction, ignore! */
270 /* We're just an intermediary peer, route the message along its path */
271 route = get_route (cid);
275 destroy_route (route);
280 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY
282 * @param cls Closure (CadetPeer for neighbor that sent the message).
283 * @param msg Message itself.
286 handle_destroy (void *cls,
287 const struct GNUNET_CADET_ConnectionDestroy *msg)
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;
294 /* First, check if message belongs to a connection that ends here. */
295 cc = GNUNET_CONTAINER_multihashmap_get (connections,
299 /* verify message came from the right direction */
300 struct CadetPeerPath *path = GCC_get_path (cc);
303 GCPP_get_peer_at_offset (path,
306 /* received message from unexpected direction, ignore! */
314 /* We're just an intermediary peer, route the message along its path */
315 route = get_route (cid);
319 destroy_route (route);
324 * Handle for #GNUNET_MESSAGE_TYPE_CADET_ACK
326 * @param cls Closure (CadetPeer for neighbor that sent the message).
327 * @param msg Message itself.
330 handle_ack (void *cls,
331 const struct GNUNET_CADET_ACK *msg)
333 struct CadetPeer *peer = cls;
336 GCC_handle_ack (peer,
343 * Handle for #GNUNET_MESSAGE_TYPE_CADET_POLL
345 * @param cls Closure (CadetPeer for neighbor that sent the message).
346 * @param msg Message itself.
349 handle_poll (void *cls,
350 const struct GNUNET_CADET_Poll *msg)
352 struct CadetPeer *peer = cls;
355 GCC_handle_poll (peer,
362 * Handle for #GNUNET_MESSAGE_TYPE_CADET_KX
364 * @param cls Closure (CadetPeer for neighbor that sent the message).
365 * @param msg Message itself.
368 handle_kx (void *cls,
369 const struct GNUNET_CADET_KX *msg)
371 struct CadetPeer *peer = cls;
372 const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel);
373 struct CadetConnection *cc;
375 /* First, check if message belongs to a connection that ends here. */
376 cc = GNUNET_CONTAINER_multihashmap_get (connections,
380 /* verify message came from the right direction */
381 struct CadetPeerPath *path = GCC_get_path (cc);
384 GCPP_get_peer_at_offset (path,
387 /* received message from unexpected direction, ignore! */
396 /* We're just an intermediary peer, route the message along its path */
404 * Check if the encrypted message has the appropriate size.
406 * @param cls Closure (unused).
407 * @param msg Message to check.
409 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
412 check_encrypted (void *cls,
413 const struct GNUNET_CADET_Encrypted *msg)
420 * Handle for #GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED.
422 * @param cls Closure (CadetPeer for neighbor that sent the message).
423 * @param msg Message itself.
426 handle_encrypted (void *cls,
427 const struct GNUNET_CADET_Encrypted *msg)
429 struct CadetPeer *peer = cls;
430 const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel);
431 struct CadetConnection *cc;
433 /* First, check if message belongs to a connection that ends here. */
434 cc = GNUNET_CONTAINER_multihashmap_get (connections,
438 /* verify message came from the right direction */
439 struct CadetPeerPath *path = GCC_get_path (cc);
442 GCPP_get_peer_at_offset (path,
445 /* received message from unexpected direction, ignore! */
449 GCC_handle_encrypted (cc,
454 /* We're just an intermediary peer, route the message along its path */
462 * Function called after #GNUNET_CORE_connect has succeeded (or failed
463 * for good). Note that the private key of the peer is intentionally
464 * not exposed here; if you need it, your process should try to read
465 * the private key file directly (which should work if you are
466 * authorized...). Implementations of this function must not call
467 * #GNUNET_CORE_disconnect (other than by scheduling a new task to
471 * @param my_identity ID of this peer, NULL if we failed
474 core_init_cb (void *cls,
475 const struct GNUNET_PeerIdentity *my_identity)
477 if (NULL == my_identity)
485 sizeof (struct GNUNET_PeerIdentity)));
490 * Method called whenever a given peer connects.
493 * @param peer peer identity this notification is about
496 core_connect_cb (void *cls,
497 const struct GNUNET_PeerIdentity *peer,
498 struct GNUNET_MQ_Handle *mq)
500 struct CadetPeer *cp;
511 * Method called whenever a peer disconnects.
514 * @param peer peer identity this notification is about
517 core_disconnect_cb (void *cls,
518 const struct GNUNET_PeerIdentity *peer,
521 struct CadetPeer *cp = peer_cls;
523 /* FIXME: also check all routes going via peer and
524 send broken messages to the other direction! */
532 * Initialize the CORE subsystem.
534 * @param c Configuration.
537 GCO_init (const struct GNUNET_CONFIGURATION_Handle *c)
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,
544 GNUNET_MQ_hd_fixed_size (connection_ack,
545 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK,
546 struct GNUNET_CADET_ConnectionACK,
548 GNUNET_MQ_hd_fixed_size (broken,
549 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN,
550 struct GNUNET_CADET_ConnectionBroken,
552 GNUNET_MQ_hd_fixed_size (destroy,
553 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY,
554 struct GNUNET_CADET_ConnectionDestroy,
556 GNUNET_MQ_hd_fixed_size (ack,
557 GNUNET_MESSAGE_TYPE_CADET_ACK,
558 struct GNUNET_CADET_ACK,
560 GNUNET_MQ_hd_fixed_size (poll,
561 GNUNET_MESSAGE_TYPE_CADET_POLL,
562 struct GNUNET_CADET_Poll,
564 GNUNET_MQ_hd_fixed_size (kx,
565 GNUNET_MESSAGE_TYPE_CADET_KX,
566 struct GNUNET_CADET_KX,
568 GNUNET_MQ_hd_var_size (encrypted,
569 GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED,
570 struct GNUNET_CADET_Encrypted,
572 GNUNET_MQ_handler_end ()
575 routes = GNUNET_CONTAINER_multihashmap_create (1024,
577 core = GNUNET_CORE_connect (c,
587 * Shut down the CORE subsystem.
594 GNUNET_CORE_disconnect (core);
597 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (routes));
598 GNUNET_CONTAINER_multihashmap_destroy (routes);
601 /* end of gnunet-cadet-service_core.c */