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_ConnectionBrokenMessage *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_connection_create (void *cls,
141 const struct GNUNET_CADET_ConnectionCreateMessage *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_connection_create (void *cls,
174 const struct GNUNET_CADET_ConnectionCreateMessage *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_CREATE_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_ConnectionCreateMessageAckMessage *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_connection_broken (void *cls,
239 const struct GNUNET_CADET_ConnectionBrokenMessage *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! */
263 /* FIXME: also destroy the path up to the specified link! */
267 /* We're just an intermediary peer, route the message along its path */
268 route = get_route (&msg->cid);
272 destroy_route (route);
273 /* FIXME: also destroy paths we MAY have up to the specified link! */
278 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY
280 * @param cls Closure (CadetPeer for neighbor that sent the message).
281 * @param msg Message itself.
284 handle_connection_destroy (void *cls,
285 const struct GNUNET_CADET_ConnectionDestroyMessage *msg)
287 struct CadetPeer *peer = cls;
288 struct CadetConnection *cc;
289 struct CadetRoute *route;
291 /* First, check if message belongs to a connection that ends here. */
292 cc = GNUNET_CONTAINER_multishortmap_get (connections,
293 &msg->cid.connection_of_tunnel);
296 /* verify message came from the right direction */
297 struct CadetPeerPath *path = GCC_get_path (cc);
300 GCPP_get_peer_at_offset (path,
303 /* received message from unexpected direction, ignore! */
311 /* We're just an intermediary peer, route the message along its path */
312 route = get_route (&msg->cid);
316 destroy_route (route);
321 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_HOP_BY_HOP_ENCRYPTED_ACK.
323 * @param cls Closure (CadetPeer for neighbor that sent the message).
324 * @param msg Message itself.
327 handle_hop_by_hop_encrypted_ack (void *cls,
328 const struct GNUNET_CADET_ConnectionEncryptedAckMessage *msg)
330 struct CadetPeer *peer = cls;
333 GCC_handle_poll (peer,
340 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL
342 * @param cls Closure (CadetPeer for neighbor that sent the message).
343 * @param msg Message itself.
346 handle_poll (void *cls,
347 const struct GNUNET_CADET_ConnectionHopByHopPollMessage *msg)
349 struct CadetPeer *peer = cls;
352 GCC_handle_poll (peer,
359 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX
361 * @param cls Closure (CadetPeer for neighbor that sent the message).
362 * @param msg Message itself.
365 handle_tunnel_kx (void *cls,
366 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
368 struct CadetPeer *peer = cls;
369 struct CadetConnection *cc;
371 /* First, check if message belongs to a connection that ends here. */
372 cc = GNUNET_CONTAINER_multishortmap_get (connections,
373 &msg->cid.connection_of_tunnel);
376 /* verify message came from the right direction */
377 struct CadetPeerPath *path = GCC_get_path (cc);
380 GCPP_get_peer_at_offset (path,
383 /* received message from unexpected direction, ignore! */
392 /* We're just an intermediary peer, route the message along its path */
400 * Check if the encrypted message has the appropriate size.
402 * @param cls Closure (unused).
403 * @param msg Message to check.
405 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
408 check_tunnel_encrypted (void *cls,
409 const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
416 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED.
418 * @param cls Closure (CadetPeer for neighbor that sent the message).
419 * @param msg Message itself.
422 handle_tunnel_encrypted (void *cls,
423 const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
425 struct CadetPeer *peer = cls;
426 struct CadetConnection *cc;
428 /* First, check if message belongs to a connection that ends here. */
429 cc = GNUNET_CONTAINER_multishortmap_get (connections,
430 &msg->cid.connection_of_tunnel);
433 /* verify message came from the right direction */
434 struct CadetPeerPath *path = GCC_get_path (cc);
437 GCPP_get_peer_at_offset (path,
440 /* received message from unexpected direction, ignore! */
444 GCC_handle_encrypted (cc,
449 /* We're just an intermediary peer, route the message along its path */
457 * Function called after #GNUNET_CORE_connect has succeeded (or failed
458 * for good). Note that the private key of the peer is intentionally
459 * not exposed here; if you need it, your process should try to read
460 * the private key file directly (which should work if you are
461 * authorized...). Implementations of this function must not call
462 * #GNUNET_CORE_disconnect (other than by scheduling a new task to
466 * @param my_identity ID of this peer, NULL if we failed
469 core_init_cb (void *cls,
470 const struct GNUNET_PeerIdentity *my_identity)
472 if (NULL == my_identity)
480 sizeof (struct GNUNET_PeerIdentity)));
485 * Method called whenever a given peer connects.
488 * @param peer peer identity this notification is about
491 core_connect_cb (void *cls,
492 const struct GNUNET_PeerIdentity *peer,
493 struct GNUNET_MQ_Handle *mq)
495 struct CadetPeer *cp;
506 * Method called whenever a peer disconnects.
509 * @param peer peer identity this notification is about
512 core_disconnect_cb (void *cls,
513 const struct GNUNET_PeerIdentity *peer,
516 struct CadetPeer *cp = peer_cls;
518 /* FIXME: also check all routes going via peer and
519 send broken messages to the other direction! */
527 * Initialize the CORE subsystem.
529 * @param c Configuration.
532 GCO_init (const struct GNUNET_CONFIGURATION_Handle *c)
534 struct GNUNET_MQ_MessageHandler handlers[] = {
535 GNUNET_MQ_hd_var_size (connection_create,
536 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE,
537 struct GNUNET_CADET_ConnectionCreateMessage,
539 GNUNET_MQ_hd_fixed_size (connection_ack,
540 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK,
541 struct GNUNET_CADET_ConnectionCreateMessageAckMessage,
543 GNUNET_MQ_hd_fixed_size (connection_broken,
544 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN,
545 struct GNUNET_CADET_ConnectionBrokenMessage,
547 GNUNET_MQ_hd_fixed_size (connection_destroy,
548 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY,
549 struct GNUNET_CADET_ConnectionDestroyMessage,
551 GNUNET_MQ_hd_fixed_size (hop_by_hop_encrypted_ack,
552 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK,
553 struct GNUNET_CADET_ConnectionEncryptedAckMessage,
555 GNUNET_MQ_hd_fixed_size (poll,
556 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL,
557 struct GNUNET_CADET_ConnectionHopByHopPollMessage,
559 GNUNET_MQ_hd_fixed_size (tunnel_kx,
560 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX,
561 struct GNUNET_CADET_TunnelKeyExchangeMessage,
563 GNUNET_MQ_hd_var_size (tunnel_encrypted,
564 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED,
565 struct GNUNET_CADET_TunnelEncryptedMessage,
567 GNUNET_MQ_handler_end ()
570 routes = GNUNET_CONTAINER_multishortmap_create (1024,
572 core = GNUNET_CORE_connect (c,
582 * Shut down the CORE subsystem.
589 GNUNET_CORE_disconnect (core);
592 GNUNET_assert (0 == GNUNET_CONTAINER_multishortmap_size (routes));
593 GNUNET_CONTAINER_multishortmap_destroy (routes);
596 /* end of gnunet-cadet-service_core.c */