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 * - properly implement GLOBAL message buffer, instead of per-route buffers
31 * - do NOT use buffering if the route options say no buffer!
32 * - Optimization: given BROKEN messages, destroy paths (?)
35 #include "gnunet-service-cadet-new_core.h"
36 #include "gnunet-service-cadet-new_paths.h"
37 #include "gnunet-service-cadet-new_peer.h"
38 #include "gnunet-service-cadet-new_connection.h"
39 #include "gnunet-service-cadet-new_tunnels.h"
40 #include "gnunet_core_service.h"
41 #include "gnunet_statistics_service.h"
42 #include "cadet_protocol.h"
45 #define LOG(level, ...) GNUNET_log_from(level,"cadet-cor",__VA_ARGS__)
49 * Number of messages we are willing to buffer per route.
50 * FIXME: have global buffer pool instead!
52 #define ROUTE_BUFFER_SIZE 8
56 * Information we keep per direction for a route.
63 struct CadetPeer *hop;
66 * Route this direction is part of.
68 struct CadetRoute *my_route;
71 * Message queue manager for @e hop.
73 struct GCP_MessageQueueManager *mqm;
76 * Cyclic message buffer to @e hop.
78 struct GNUNET_MQ_Envelope *out_buffer[ROUTE_BUFFER_SIZE];
81 * Next write offset to use to append messages to @e out_buffer.
83 unsigned int out_wpos;
86 * Next read offset to use to retrieve messages from @e out_buffer.
88 unsigned int out_rpos;
91 * Is @e mqm currently ready for transmission?
99 * Description of a segment of a `struct CadetConnection` at the
100 * intermediate peers. Routes are basically entries in a peer's
101 * routing table for forwarding traffic. At both endpoints, the
102 * routes are terminated by a `struct CadetConnection`, which knows
103 * the complete `struct CadetPath` that is formed by the individual
110 * Information about the next hop on this route.
112 struct RouteDirection next;
115 * Information about the previous hop on this route.
117 struct RouteDirection prev;
120 * Unique identifier for the connection that uses this route.
122 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
125 * When was this route last in use?
127 struct GNUNET_TIME_Absolute last_use;
130 * Position of this route in the #route_heap.
132 struct GNUNET_CONTAINER_HeapNode *hn;
135 * Options for the route, control buffering.
137 enum GNUNET_CADET_ChannelOption options;
142 * Handle to the CORE service.
144 static struct GNUNET_CORE_Handle *core;
147 * Routes on which this peer is an intermediate.
149 static struct GNUNET_CONTAINER_MultiShortmap *routes;
152 * Heap of routes, MIN-sorted by last activity.
154 static struct GNUNET_CONTAINER_Heap *route_heap;
157 * Maximum number of concurrent routes this peer will support.
159 static unsigned long long max_routes;
162 * Task to timeout routes.
164 static struct GNUNET_SCHEDULER_Task *timeout_task;
168 * Get the route corresponding to a hash.
170 * @param cid hash generated from the connection identifier
172 static struct CadetRoute *
173 get_route (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
175 return GNUNET_CONTAINER_multishortmap_get (routes,
176 &cid->connection_of_tunnel);
181 * We message @a msg from @a prev. Find its route by @a cid and
182 * forward to the next hop. Drop and signal broken route if we do not
185 * @param prev previous hop (sender)
186 * @param cid connection identifier, tells us which route to use
187 * @param msg the message to forward
190 route_message (struct CadetPeer *prev,
191 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
192 const struct GNUNET_MessageHeader *msg)
194 struct CadetRoute *route;
195 struct RouteDirection *dir;
196 struct GNUNET_MQ_Envelope *env;
198 route = get_route (cid);
201 struct GNUNET_MQ_Envelope *env;
202 struct GNUNET_CADET_ConnectionBrokenMessage *bm;
204 LOG (GNUNET_ERROR_TYPE_DEBUG,
205 "Failed to route message of type %u from %s on connection %s: no route\n",
208 GNUNET_sh2s (&cid->connection_of_tunnel));
209 env = GNUNET_MQ_msg (bm,
210 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
212 bm->peer1 = my_full_id;
217 route->last_use = GNUNET_TIME_absolute_get ();
218 GNUNET_CONTAINER_heap_update_cost (route->hn,
219 route->last_use.abs_value_us);
220 dir = (prev == route->prev.hop) ? &route->next : &route->prev;
221 if (GNUNET_YES == dir->is_ready)
223 LOG (GNUNET_ERROR_TYPE_DEBUG,
224 "Routing message of type %u from %s to %s on connection %s\n",
227 GNUNET_i2s (GCP_get_id (dir->hop)),
228 GNUNET_sh2s (&cid->connection_of_tunnel));
229 dir->is_ready = GNUNET_NO;
231 GNUNET_MQ_msg_copy (msg));
234 env = dir->out_buffer[dir->out_wpos];
237 /* Queue full, drop earliest message in queue */
238 LOG (GNUNET_ERROR_TYPE_DEBUG,
239 "Queue full due to new message of type %u from %s to %s on connection %s, dropping old message\n",
242 GNUNET_i2s (GCP_get_id (dir->hop)),
243 GNUNET_sh2s (&cid->connection_of_tunnel));
244 GNUNET_STATISTICS_update (stats,
245 "# messages dropped due to full buffer",
248 GNUNET_assert (dir->out_rpos == dir->out_wpos);
249 GNUNET_MQ_discard (env);
251 if (ROUTE_BUFFER_SIZE == dir->out_rpos)
254 LOG (GNUNET_ERROR_TYPE_DEBUG,
255 "Queueing new message of type %u from %s to %s on connection %s\n",
258 GNUNET_i2s (GCP_get_id (dir->hop)),
259 GNUNET_sh2s (&cid->connection_of_tunnel));
260 env = GNUNET_MQ_msg_copy (msg);
261 dir->out_buffer[dir->out_wpos] = env;
263 if (ROUTE_BUFFER_SIZE == dir->out_wpos)
269 * Check if the create_connection message has the appropriate size.
271 * @param cls Closure (unused).
272 * @param msg Message to check.
274 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
277 check_connection_create (void *cls,
278 const struct GNUNET_CADET_ConnectionCreateMessage *msg)
280 uint16_t size = ntohs (msg->header.size) - sizeof (*msg);
282 if (0 != (size % sizeof (struct GNUNET_PeerIdentity)))
292 * Free internal data of a route direction.
294 * @param dir direction to destroy (do NOT free memory of 'dir' itself)
297 destroy_direction (struct RouteDirection *dir)
299 for (unsigned int i=0;i<ROUTE_BUFFER_SIZE;i++)
300 if (NULL != dir->out_buffer[i])
302 GNUNET_MQ_discard (dir->out_buffer[i]);
303 dir->out_buffer[i] = NULL;
305 if (NULL != dir->mqm)
307 GCP_request_mq_cancel (dir->mqm,
315 * Destroy our state for @a route.
317 * @param route route to destroy
320 destroy_route (struct CadetRoute *route)
322 LOG (GNUNET_ERROR_TYPE_DEBUG,
323 "Destroying route from %s to %s of connection %s\n",
324 GNUNET_i2s (GCP_get_id (route->prev.hop)),
325 GNUNET_i2s2 (GCP_get_id (route->next.hop)),
326 GNUNET_sh2s (&route->cid.connection_of_tunnel));
327 GNUNET_assert (route ==
328 GNUNET_CONTAINER_heap_remove_node (route->hn));
329 GNUNET_assert (GNUNET_YES ==
330 GNUNET_CONTAINER_multishortmap_remove (routes,
331 &route->cid.connection_of_tunnel,
333 destroy_direction (&route->prev);
334 destroy_direction (&route->next);
340 * Send message that a route is broken between @a peer1 and @a peer2.
342 * @param target where to send the message
343 * @param cid connection identifier to use
344 * @param peer1 one of the peers where a link is broken
345 * @param peer2 another one of the peers where a link is broken
348 send_broken (struct RouteDirection *target,
349 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
350 const struct GNUNET_PeerIdentity *peer1,
351 const struct GNUNET_PeerIdentity *peer2)
353 struct GNUNET_MQ_Envelope *env;
354 struct GNUNET_CADET_ConnectionBrokenMessage *bm;
356 if (NULL == target->mqm)
357 return; /* Can't send notification, connection is down! */
358 LOG (GNUNET_ERROR_TYPE_DEBUG,
359 "Notifying %s about BROKEN route at %s-%s of connection %s\n",
360 GCP_2s (target->hop),
363 GNUNET_sh2s (&cid->connection_of_tunnel));
365 env = GNUNET_MQ_msg (bm,
366 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
373 GCP_request_mq_cancel (target->mqm,
380 * Function called to check if any routes have timed out, and if
381 * so, to clean them up. Finally, schedules itself again at the
382 * earliest time where there might be more work.
387 timeout_cb (void *cls)
389 struct CadetRoute *r;
390 struct GNUNET_TIME_Relative linger;
391 struct GNUNET_TIME_Absolute exp;
394 linger = GNUNET_TIME_relative_multiply (keepalive_period,
396 while (NULL != (r = GNUNET_CONTAINER_heap_peek (route_heap)))
398 exp = GNUNET_TIME_absolute_add (r->last_use,
400 if (0 != GNUNET_TIME_absolute_get_duration (exp).rel_value_us)
402 /* Route not yet timed out, wait until it does. */
403 timeout_task = GNUNET_SCHEDULER_add_at (exp,
408 send_broken (&r->prev,
412 send_broken (&r->next,
418 /* No more routes left, so no need for a #timeout_task */
423 * Function called when the message queue to the previous hop
424 * becomes available/unavailable. We expect this function to
425 * be called immediately when we register, and then again
426 * later if the connection ever goes down.
428 * @param cls the `struct RouteDirection`
429 * @param available #GNUNET_YES if sending is now possible,
430 * #GNUNET_NO if sending is no longer possible
431 * #GNUNET_SYSERR if sending is no longer possible
432 * and the last envelope was discarded
435 dir_ready_cb (void *cls,
438 struct RouteDirection *dir = cls;
439 struct CadetRoute *route = dir->my_route;
440 struct RouteDirection *odir;
442 if (GNUNET_YES == ready)
444 struct GNUNET_MQ_Envelope *env;
446 dir->is_ready = GNUNET_YES;
447 if (NULL != (env = dir->out_buffer[dir->out_rpos]))
449 dir->out_buffer[dir->out_rpos] = NULL;
451 if (ROUTE_BUFFER_SIZE == dir->out_rpos)
453 dir->is_ready = GNUNET_NO;
459 odir = (dir == &route->next) ? &route->prev : &route->next;
460 send_broken (&route->next,
462 GCP_get_id (odir->hop),
464 destroy_route (route);
469 * Initialize one of the directions of a route.
471 * @param route route the direction belongs to
472 * @param dir direction to initialize
473 * @param hop next hop on in the @a dir
476 dir_init (struct RouteDirection *dir,
477 struct CadetRoute *route,
478 struct CadetPeer *hop)
481 dir->my_route = route;
482 dir->mqm = GCP_request_mq (hop,
485 GNUNET_assert (GNUNET_YES == dir->is_ready);
490 * We could not create the desired route. Send a
491 * #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
492 * message to @a target.
494 * @param target who should receive the message
495 * @param cid identifier of the connection/route that failed
496 * @param failure_at neighbour with which we failed to route,
500 send_broken_without_mqm (struct CadetPeer *target,
501 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
502 const struct GNUNET_PeerIdentity *failure_at)
504 struct GNUNET_MQ_Envelope *env;
505 struct GNUNET_CADET_ConnectionBrokenMessage *bm;
507 env = GNUNET_MQ_msg (bm,
508 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
510 bm->peer1 = my_full_id;
511 if (NULL != failure_at)
512 bm->peer2 = *failure_at;
513 GCP_send_ooo (target,
519 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE
521 * @param cls Closure (CadetPeer for neighbor that sent the message).
522 * @param msg Message itself.
525 handle_connection_create (void *cls,
526 const struct GNUNET_CADET_ConnectionCreateMessage *msg)
528 struct CadetPeer *sender = cls;
529 struct CadetPeer *next;
530 const struct GNUNET_PeerIdentity *pids = (const struct GNUNET_PeerIdentity *) &msg[1];
531 struct CadetRoute *route;
532 uint16_t size = ntohs (msg->header.size) - sizeof (*msg);
533 unsigned int path_length;
535 enum GNUNET_CADET_ChannelOption options;
537 options = (enum GNUNET_CADET_ChannelOption) ntohl (msg->options);
538 path_length = size / sizeof (struct GNUNET_PeerIdentity);
539 /* Initiator is at offset 0. */
540 for (off=1;off<path_length;off++)
541 if (0 == memcmp (&my_full_id,
543 sizeof (struct GNUNET_PeerIdentity)))
545 if (off == path_length)
547 /* We are not on the path, bogus request */
551 /* Check previous hop */
552 if (sender != GCP_get (&pids[off - 1],
555 /* sender is not on the path, not allowed */
560 get_route (&msg->cid))
562 /* Duplicate CREATE, pass it on, previous one might have been lost! */
563 LOG (GNUNET_ERROR_TYPE_DEBUG,
564 "Passing on duplicate CADET_CONNECTION_CREATE message on connection %s\n",
565 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
566 route_message (sender,
571 if (off == path_length - 1)
573 /* We are the destination, create connection */
574 struct CadetConnection *cc;
575 struct CadetPeerPath *path;
576 struct CadetPeer *origin;
578 cc = GNUNET_CONTAINER_multishortmap_get (connections,
579 &msg->cid.connection_of_tunnel);
582 LOG (GNUNET_ERROR_TYPE_DEBUG,
583 "Received duplicate CADET_CONNECTION_CREATE message on connection %s\n",
584 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
585 GCC_handle_duplicate_create (cc);
589 origin = GCP_get (&pids[0],
591 LOG (GNUNET_ERROR_TYPE_DEBUG,
592 "Received CADET_CONNECTION_CREATE message from %s for connection %s, building inverse path\n",
594 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
595 path = GCPP_get_path_from_route (path_length - 1,
598 GCT_add_inbound_connection (GCP_get_tunnel (origin,
601 (enum GNUNET_CADET_ChannelOption) ntohl (msg->options),
604 /* Send back BROKEN: duplicate connection on the same path,
605 we will use the other one. */
606 LOG (GNUNET_ERROR_TYPE_DEBUG,
607 "Received CADET_CONNECTION_CREATE from %s for %s, but %s already has a connection. Sending BROKEN\n",
609 GNUNET_sh2s (&msg->cid.connection_of_tunnel),
611 send_broken_without_mqm (sender,
618 /* We are merely a hop on the way, check if we can support the route */
619 next = GCP_get (&pids[off + 1],
621 if ( (NULL == next) ||
622 (GNUNET_NO == GCP_has_core_connection (next)) )
624 /* unworkable, send back BROKEN notification */
625 LOG (GNUNET_ERROR_TYPE_DEBUG,
626 "Received CADET_CONNECTION_CREATE from %s for %s. Next hop %s:%u is down. Sending BROKEN\n",
628 GNUNET_sh2s (&msg->cid.connection_of_tunnel),
629 GNUNET_i2s (&pids[off + 1]),
631 send_broken_without_mqm (sender,
636 if (max_routes <= GNUNET_CONTAINER_multishortmap_size (routes))
638 LOG (GNUNET_ERROR_TYPE_DEBUG,
639 "Received CADET_CONNECTION_CREATE from %s for %s. We have reached our route limit. Sending BROKEN\n",
641 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
642 send_broken_without_mqm (sender,
648 /* Workable route, create routing entry */
649 LOG (GNUNET_ERROR_TYPE_DEBUG,
650 "Received CADET_CONNECTION_CREATE from %s for %s. Next hop %s:%u is up. Creating route\n",
652 GNUNET_sh2s (&msg->cid.connection_of_tunnel),
653 GNUNET_i2s (&pids[off + 1]),
655 route = GNUNET_new (struct CadetRoute);
656 route->options = options;
657 route->cid = msg->cid;
658 route->last_use = GNUNET_TIME_absolute_get ();
659 dir_init (&route->prev,
662 dir_init (&route->next,
665 GNUNET_assert (GNUNET_OK ==
666 GNUNET_CONTAINER_multishortmap_put (routes,
667 &route->cid.connection_of_tunnel,
669 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
670 route->hn = GNUNET_CONTAINER_heap_insert (route_heap,
672 route->last_use.abs_value_us);
673 if (NULL == timeout_task)
674 timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (keepalive_period,
682 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK
684 * @param cls Closure (CadetPeer for neighbor that sent the message).
685 * @param msg Message itself.
688 handle_connection_create_ack (void *cls,
689 const struct GNUNET_CADET_ConnectionCreateAckMessage *msg)
691 struct CadetPeer *peer = cls;
692 struct CadetConnection *cc;
694 /* First, check if ACK belongs to a connection that ends here. */
695 cc = GNUNET_CONTAINER_multishortmap_get (connections,
696 &msg->cid.connection_of_tunnel);
699 /* verify ACK came from the right direction */
700 struct CadetPeerPath *path = GCC_get_path (cc);
703 GCPP_get_peer_at_offset (path,
706 /* received ACK from unexpected direction, ignore! */
710 LOG (GNUNET_ERROR_TYPE_DEBUG,
711 "Received CONNECTION_CREATE_ACK for connection %s.\n",
712 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
713 GCC_handle_connection_create_ack (cc);
717 /* We're just an intermediary peer, route the message along its path */
725 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
727 * @param cls Closure (CadetPeer for neighbor that sent the message).
728 * @param msg Message itself.
729 * @deprecated duplicate logic with #handle_destroy(); dedup!
732 handle_connection_broken (void *cls,
733 const struct GNUNET_CADET_ConnectionBrokenMessage *msg)
735 struct CadetPeer *peer = cls;
736 struct CadetConnection *cc;
737 struct CadetRoute *route;
739 /* First, check if message belongs to a connection that ends here. */
740 cc = GNUNET_CONTAINER_multishortmap_get (connections,
741 &msg->cid.connection_of_tunnel);
744 /* verify message came from the right direction */
745 struct CadetPeerPath *path = GCC_get_path (cc);
748 GCPP_get_peer_at_offset (path,
751 /* received message from unexpected direction, ignore! */
755 LOG (GNUNET_ERROR_TYPE_DEBUG,
756 "Received CONNECTION_BROKEN for connection %s. Destroying it.\n",
757 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
758 GCC_destroy_without_core (cc);
760 /* FIXME: also destroy the path up to the specified link! */
764 /* We're just an intermediary peer, route the message along its path */
765 route = get_route (&msg->cid);
769 destroy_route (route);
770 /* FIXME: also destroy paths we MAY have up to the specified link! */
775 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY
777 * @param cls Closure (CadetPeer for neighbor that sent the message).
778 * @param msg Message itself.
781 handle_connection_destroy (void *cls,
782 const struct GNUNET_CADET_ConnectionDestroyMessage *msg)
784 struct CadetPeer *peer = cls;
785 struct CadetConnection *cc;
786 struct CadetRoute *route;
788 /* First, check if message belongs to a connection that ends here. */
789 cc = GNUNET_CONTAINER_multishortmap_get (connections,
790 &msg->cid.connection_of_tunnel);
793 /* verify message came from the right direction */
794 struct CadetPeerPath *path = GCC_get_path (cc);
797 GCPP_get_peer_at_offset (path,
800 /* received message from unexpected direction, ignore! */
804 LOG (GNUNET_ERROR_TYPE_DEBUG,
805 "Received CONNECTION_DESTROY for connection %s. Destroying connection.\n",
806 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
808 GCC_destroy_without_core (cc);
812 /* We're just an intermediary peer, route the message along its path */
813 LOG (GNUNET_ERROR_TYPE_DEBUG,
814 "Received CONNECTION_DESTROY for connection %s. Destroying route.\n",
815 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
816 route = get_route (&msg->cid);
820 destroy_route (route);
825 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX
827 * @param cls Closure (CadetPeer for neighbor that sent the message).
828 * @param msg Message itself.
831 handle_tunnel_kx (void *cls,
832 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
834 struct CadetPeer *peer = cls;
835 struct CadetConnection *cc;
837 /* First, check if message belongs to a connection that ends here. */
838 cc = GNUNET_CONTAINER_multishortmap_get (connections,
839 &msg->cid.connection_of_tunnel);
842 /* verify message came from the right direction */
843 struct CadetPeerPath *path = GCC_get_path (cc);
846 GCPP_get_peer_at_offset (path,
849 /* received message from unexpected direction, ignore! */
858 /* We're just an intermediary peer, route the message along its path */
866 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH
868 * @param cls Closure (CadetPeer for neighbor that sent the message).
869 * @param msg Message itself.
872 handle_tunnel_kx_auth (void *cls,
873 const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
875 struct CadetPeer *peer = cls;
876 struct CadetConnection *cc;
878 /* First, check if message belongs to a connection that ends here. */
879 cc = GNUNET_CONTAINER_multishortmap_get (connections,
880 &msg->kx.cid.connection_of_tunnel);
883 /* verify message came from the right direction */
884 struct CadetPeerPath *path = GCC_get_path (cc);
887 GCPP_get_peer_at_offset (path,
890 /* received message from unexpected direction, ignore! */
894 GCC_handle_kx_auth (cc,
899 /* We're just an intermediary peer, route the message along its path */
907 * Check if the encrypted message has the appropriate size.
909 * @param cls Closure (unused).
910 * @param msg Message to check.
912 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
915 check_tunnel_encrypted (void *cls,
916 const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
923 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED.
925 * @param cls Closure (CadetPeer for neighbor that sent the message).
926 * @param msg Message itself.
929 handle_tunnel_encrypted (void *cls,
930 const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
932 struct CadetPeer *peer = cls;
933 struct CadetConnection *cc;
935 /* First, check if message belongs to a connection that ends here. */
936 cc = GNUNET_CONTAINER_multishortmap_get (connections,
937 &msg->cid.connection_of_tunnel);
940 /* verify message came from the right direction */
941 struct CadetPeerPath *path = GCC_get_path (cc);
944 GCPP_get_peer_at_offset (path,
947 /* received message from unexpected direction, ignore! */
951 GCC_handle_encrypted (cc,
955 /* We're just an intermediary peer, route the message along its path */
963 * Function called after #GNUNET_CORE_connect has succeeded (or failed
964 * for good). Note that the private key of the peer is intentionally
965 * not exposed here; if you need it, your process should try to read
966 * the private key file directly (which should work if you are
967 * authorized...). Implementations of this function must not call
968 * #GNUNET_CORE_disconnect (other than by scheduling a new task to
972 * @param my_identity ID of this peer, NULL if we failed
975 core_init_cb (void *cls,
976 const struct GNUNET_PeerIdentity *my_identity)
978 if (NULL == my_identity)
986 sizeof (struct GNUNET_PeerIdentity)));
991 * Method called whenever a given peer connects.
994 * @param peer peer identity this notification is about
997 core_connect_cb (void *cls,
998 const struct GNUNET_PeerIdentity *peer,
999 struct GNUNET_MQ_Handle *mq)
1001 struct CadetPeer *cp;
1003 LOG (GNUNET_ERROR_TYPE_DEBUG,
1004 "CORE connection to peer %s was established.\n",
1015 * Method called whenever a peer disconnects.
1017 * @param cls closure
1018 * @param peer peer identity this notification is about
1021 core_disconnect_cb (void *cls,
1022 const struct GNUNET_PeerIdentity *peer,
1025 struct CadetPeer *cp = peer_cls;
1027 LOG (GNUNET_ERROR_TYPE_DEBUG,
1028 "CORE connection to peer %s went down.\n",
1036 * Initialize the CORE subsystem.
1038 * @param c Configuration.
1041 GCO_init (const struct GNUNET_CONFIGURATION_Handle *c)
1043 struct GNUNET_MQ_MessageHandler handlers[] = {
1044 GNUNET_MQ_hd_var_size (connection_create,
1045 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE,
1046 struct GNUNET_CADET_ConnectionCreateMessage,
1048 GNUNET_MQ_hd_fixed_size (connection_create_ack,
1049 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK,
1050 struct GNUNET_CADET_ConnectionCreateAckMessage,
1052 GNUNET_MQ_hd_fixed_size (connection_broken,
1053 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN,
1054 struct GNUNET_CADET_ConnectionBrokenMessage,
1056 GNUNET_MQ_hd_fixed_size (connection_destroy,
1057 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY,
1058 struct GNUNET_CADET_ConnectionDestroyMessage,
1060 GNUNET_MQ_hd_fixed_size (tunnel_kx,
1061 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX,
1062 struct GNUNET_CADET_TunnelKeyExchangeMessage,
1064 GNUNET_MQ_hd_fixed_size (tunnel_kx_auth,
1065 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH,
1066 struct GNUNET_CADET_TunnelKeyExchangeAuthMessage,
1068 GNUNET_MQ_hd_var_size (tunnel_encrypted,
1069 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED,
1070 struct GNUNET_CADET_TunnelEncryptedMessage,
1072 GNUNET_MQ_handler_end ()
1076 GNUNET_CONFIGURATION_get_value_number (c,
1081 routes = GNUNET_CONTAINER_multishortmap_create (1024,
1083 route_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1084 core = GNUNET_CORE_connect (c,
1088 &core_disconnect_cb,
1094 * Shut down the CORE subsystem.
1101 GNUNET_CORE_disconnect (core);
1104 GNUNET_assert (0 == GNUNET_CONTAINER_multishortmap_size (routes));
1105 GNUNET_CONTAINER_multishortmap_destroy (routes);
1107 GNUNET_CONTAINER_heap_destroy (route_heap);
1109 if (NULL != timeout_task)
1111 GNUNET_SCHEDULER_cancel (timeout_task);
1112 timeout_task = NULL;
1116 /* end of gnunet-cadet-service_core.c */