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.
51 #define ROUTE_BUFFER_SIZE 8
55 * Information we keep per direction for a route.
62 struct CadetPeer *hop;
65 * Route this direction is part of.
67 struct CadetRoute *my_route;
70 * Message queue manager for @e hop.
72 struct GCP_MessageQueueManager *mqm;
75 * Cyclic message buffer to @e hop.
77 struct GNUNET_MQ_Envelope *out_buffer[ROUTE_BUFFER_SIZE];
80 * Next write offset to use to append messages to @e out_buffer.
82 unsigned int out_wpos;
85 * Next read offset to use to retrieve messages from @e out_buffer.
87 unsigned int out_rpos;
90 * Is @e mqm currently ready for transmission?
98 * Description of a segment of a `struct CadetConnection` at the
99 * intermediate peers. Routes are basically entries in a peer's
100 * routing table for forwarding traffic. At both endpoints, the
101 * routes are terminated by a `struct CadetConnection`, which knows
102 * the complete `struct CadetPath` that is formed by the individual
109 * Information about the next hop on this route.
111 struct RouteDirection next;
114 * Information about the previous hop on this route.
116 struct RouteDirection prev;
119 * Unique identifier for the connection that uses this route.
121 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
124 * When was this route last in use?
126 struct GNUNET_TIME_Absolute last_use;
129 * Position of this route in the #route_heap.
131 struct GNUNET_CONTAINER_HeapNode *hn;
134 * Options for the route, control buffering.
136 enum GNUNET_CADET_ChannelOption options;
141 * Handle to the CORE service.
143 static struct GNUNET_CORE_Handle *core;
146 * Routes on which this peer is an intermediate.
148 static struct GNUNET_CONTAINER_MultiShortmap *routes;
151 * Heap of routes, MIN-sorted by last activity.
153 static struct GNUNET_CONTAINER_Heap *route_heap;
156 * Maximum number of concurrent routes this peer will support.
158 static unsigned long long max_routes;
161 * Task to timeout routes.
163 static struct GNUNET_SCHEDULER_Task *timeout_task;
167 * Get the route corresponding to a hash.
169 * @param cid hash generated from the connection identifier
171 static struct CadetRoute *
172 get_route (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
174 return GNUNET_CONTAINER_multishortmap_get (routes,
175 &cid->connection_of_tunnel);
180 * We message @a msg from @a prev. Find its route by @a cid and
181 * forward to the next hop. Drop and signal broken route if we do not
184 * @param prev previous hop (sender)
185 * @param cid connection identifier, tells us which route to use
186 * @param msg the message to forward
189 route_message (struct CadetPeer *prev,
190 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
191 const struct GNUNET_MessageHeader *msg)
193 struct CadetRoute *route;
194 struct RouteDirection *dir;
195 struct GNUNET_MQ_Envelope *env;
197 route = get_route (cid);
200 struct GNUNET_MQ_Envelope *env;
201 struct GNUNET_CADET_ConnectionBrokenMessage *bm;
203 LOG (GNUNET_ERROR_TYPE_DEBUG,
204 "Failed to route message of type %u from %s on connection %s: no route\n",
207 GNUNET_sh2s (&cid->connection_of_tunnel));
208 env = GNUNET_MQ_msg (bm,
209 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
211 bm->peer1 = my_full_id;
216 route->last_use = GNUNET_TIME_absolute_get ();
217 GNUNET_CONTAINER_heap_update_cost (route->hn,
218 route->last_use.abs_value_us);
219 dir = (prev == route->prev.hop) ? &route->next : &route->prev;
220 if (GNUNET_YES == dir->is_ready)
222 LOG (GNUNET_ERROR_TYPE_DEBUG,
223 "Routing message of type %u from %s to %s on connection %s\n",
226 GNUNET_i2s (GCP_get_id (dir->hop)),
227 GNUNET_sh2s (&cid->connection_of_tunnel));
228 dir->is_ready = GNUNET_NO;
230 GNUNET_MQ_msg_copy (msg));
233 env = dir->out_buffer[dir->out_wpos];
236 /* Queue full, drop earliest message in queue */
237 LOG (GNUNET_ERROR_TYPE_DEBUG,
238 "Queue full due to new message of type %u from %s to %s on connection %s, dropping old message\n",
241 GNUNET_i2s (GCP_get_id (dir->hop)),
242 GNUNET_sh2s (&cid->connection_of_tunnel));
243 GNUNET_STATISTICS_update (stats,
244 "# messages dropped due to full buffer",
247 GNUNET_assert (dir->out_rpos == dir->out_wpos);
248 GNUNET_MQ_discard (env);
250 if (ROUTE_BUFFER_SIZE == dir->out_rpos)
253 LOG (GNUNET_ERROR_TYPE_DEBUG,
254 "Queueing new message of type %u from %s to %s on connection %s\n",
257 GNUNET_i2s (GCP_get_id (dir->hop)),
258 GNUNET_sh2s (&cid->connection_of_tunnel));
259 env = GNUNET_MQ_msg_copy (msg);
260 dir->out_buffer[dir->out_wpos] = env;
262 if (ROUTE_BUFFER_SIZE == dir->out_wpos)
268 * Check if the create_connection message has the appropriate size.
270 * @param cls Closure (unused).
271 * @param msg Message to check.
273 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
276 check_connection_create (void *cls,
277 const struct GNUNET_CADET_ConnectionCreateMessage *msg)
279 uint16_t size = ntohs (msg->header.size) - sizeof (*msg);
281 if (0 != (size % sizeof (struct GNUNET_PeerIdentity)))
291 * Free internal data of a route direction.
293 * @param dir direction to destroy (do NOT free memory of 'dir' itself)
296 destroy_direction (struct RouteDirection *dir)
298 for (unsigned int i=0;i<ROUTE_BUFFER_SIZE;i++)
299 if (NULL != dir->out_buffer[i])
301 GNUNET_MQ_discard (dir->out_buffer[i]);
302 dir->out_buffer[i] = NULL;
304 if (NULL != dir->mqm)
306 GCP_request_mq_cancel (dir->mqm,
314 * Destroy our state for @a route.
316 * @param route route to destroy
319 destroy_route (struct CadetRoute *route)
321 LOG (GNUNET_ERROR_TYPE_DEBUG,
322 "Destroying route from %s to %s of connection %s\n",
323 GNUNET_i2s (GCP_get_id (route->prev.hop)),
324 GNUNET_i2s2 (GCP_get_id (route->next.hop)),
325 GNUNET_sh2s (&route->cid.connection_of_tunnel));
326 GNUNET_assert (route ==
327 GNUNET_CONTAINER_heap_remove_node (route->hn));
328 destroy_direction (&route->prev);
329 destroy_direction (&route->next);
335 * Send message that a route is broken between @a peer1 and @a peer2.
337 * @param target where to send the message
338 * @param cid connection identifier to use
339 * @param peer1 one of the peers where a link is broken
340 * @param peer2 another one of the peers where a link is broken
343 send_broken (struct RouteDirection *target,
344 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
345 const struct GNUNET_PeerIdentity *peer1,
346 const struct GNUNET_PeerIdentity *peer2)
348 struct GNUNET_MQ_Envelope *env;
349 struct GNUNET_CADET_ConnectionBrokenMessage *bm;
351 if (NULL == target->mqm)
352 return; /* Can't send notification, connection is down! */
353 LOG (GNUNET_ERROR_TYPE_DEBUG,
354 "Notifying %s about BROKEN route at %s-%s of connection %s\n",
355 GCP_2s (target->hop),
358 GNUNET_sh2s (&cid->connection_of_tunnel));
360 env = GNUNET_MQ_msg (bm,
361 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
368 GCP_request_mq_cancel (target->mqm,
375 * Function called to check if any routes have timed out, and if
376 * so, to clean them up. Finally, schedules itself again at the
377 * earliest time where there might be more work.
382 timeout_cb (void *cls)
384 struct CadetRoute *r;
385 struct GNUNET_TIME_Relative linger;
386 struct GNUNET_TIME_Absolute exp;
389 linger = GNUNET_TIME_relative_multiply (keepalive_period,
391 while (NULL != (r = GNUNET_CONTAINER_heap_peek (route_heap)))
393 exp = GNUNET_TIME_absolute_add (r->last_use,
395 if (0 != GNUNET_TIME_absolute_get_duration (exp).rel_value_us)
397 /* Route not yet timed out, wait until it does. */
398 timeout_task = GNUNET_SCHEDULER_add_at (exp,
403 send_broken (&r->prev,
407 send_broken (&r->next,
413 /* No more routes left, so no need for a #timeout_task */
418 * Function called when the message queue to the previous hop
419 * becomes available/unavailable. We expect this function to
420 * be called immediately when we register, and then again
421 * later if the connection ever goes down.
423 * @param cls the `struct RouteDirection`
424 * @param available #GNUNET_YES if sending is now possible,
425 * #GNUNET_NO if sending is no longer possible
426 * #GNUNET_SYSERR if sending is no longer possible
427 * and the last envelope was discarded
430 dir_ready_cb (void *cls,
433 struct RouteDirection *dir = cls;
434 struct CadetRoute *route = dir->my_route;
435 struct RouteDirection *odir;
437 if (GNUNET_YES == ready)
439 struct GNUNET_MQ_Envelope *env;
441 dir->is_ready = GNUNET_YES;
442 if (NULL != (env = dir->out_buffer[dir->out_rpos]))
444 dir->out_buffer[dir->out_rpos] = NULL;
446 if (ROUTE_BUFFER_SIZE == dir->out_rpos)
448 dir->is_ready = GNUNET_NO;
454 odir = (dir == &route->next) ? &route->prev : &route->next;
455 send_broken (&route->next,
457 GCP_get_id (odir->hop),
459 destroy_route (route);
464 * Initialize one of the directions of a route.
466 * @param route route the direction belongs to
467 * @param dir direction to initialize
468 * @param hop next hop on in the @a dir
471 dir_init (struct RouteDirection *dir,
472 struct CadetRoute *route,
473 struct CadetPeer *hop)
476 dir->my_route = route;
477 dir->mqm = GCP_request_mq (hop,
480 GNUNET_assert (GNUNET_YES == dir->is_ready);
485 * We could not create the desired route. Send a
486 * #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
487 * message to @a target.
489 * @param target who should receive the message
490 * @param cid identifier of the connection/route that failed
491 * @param failure_at neighbour with which we failed to route,
495 send_broken_without_mqm (struct CadetPeer *target,
496 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
497 const struct GNUNET_PeerIdentity *failure_at)
499 struct GNUNET_MQ_Envelope *env;
500 struct GNUNET_CADET_ConnectionBrokenMessage *bm;
502 env = GNUNET_MQ_msg (bm,
503 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
505 bm->peer1 = my_full_id;
506 if (NULL != failure_at)
507 bm->peer2 = *failure_at;
508 GCP_send_ooo (target,
514 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE
516 * @param cls Closure (CadetPeer for neighbor that sent the message).
517 * @param msg Message itself.
520 handle_connection_create (void *cls,
521 const struct GNUNET_CADET_ConnectionCreateMessage *msg)
523 struct CadetPeer *sender = cls;
524 struct CadetPeer *next;
525 const struct GNUNET_PeerIdentity *pids = (const struct GNUNET_PeerIdentity *) &msg[1];
526 struct CadetRoute *route;
527 uint16_t size = ntohs (msg->header.size) - sizeof (*msg);
528 unsigned int path_length;
530 enum GNUNET_CADET_ChannelOption options;
532 options = (enum GNUNET_CADET_ChannelOption) ntohl (msg->options);
533 path_length = size / sizeof (struct GNUNET_PeerIdentity);
534 /* Initiator is at offset 0. */
535 for (off=1;off<path_length;off++)
536 if (0 == memcmp (&my_full_id,
538 sizeof (struct GNUNET_PeerIdentity)))
540 if (off == path_length)
542 /* We are not on the path, bogus request */
546 /* Check previous hop */
547 if (sender != GCP_get (&pids[off - 1],
550 /* sender is not on the path, not allowed */
555 get_route (&msg->cid))
557 /* Duplicate CREATE, pass it on, previous one might have been lost! */
558 LOG (GNUNET_ERROR_TYPE_DEBUG,
559 "Passing on duplicate CADET_CONNECTION_CREATE message on connection %s\n",
560 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
561 route_message (sender,
566 if (off == path_length - 1)
568 /* We are the destination, create connection */
569 struct CadetConnection *cc;
570 struct CadetPeerPath *path;
571 struct CadetPeer *origin;
573 cc = GNUNET_CONTAINER_multishortmap_get (connections,
574 &msg->cid.connection_of_tunnel);
577 LOG (GNUNET_ERROR_TYPE_DEBUG,
578 "Received duplicate CADET_CONNECTION_CREATE message on connection %s\n",
579 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
580 GCC_handle_duplicate_create (cc);
584 origin = GCP_get (&pids[0],
586 LOG (GNUNET_ERROR_TYPE_DEBUG,
587 "Received CADET_CONNECTION_CREATE message from %s for connection %s, building inverse path\n",
589 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
590 path = GCPP_get_path_from_route (path_length - 1,
593 GCT_add_inbound_connection (GCP_get_tunnel (origin,
596 (enum GNUNET_CADET_ChannelOption) ntohl (msg->options),
599 /* Send back BROKEN: duplicate connection on the same path,
600 we will use the other one. */
601 LOG (GNUNET_ERROR_TYPE_DEBUG,
602 "Received CADET_CONNECTION_CREATE from %s for %s, but %s already has a connection. Sending BROKEN\n",
604 GNUNET_sh2s (&msg->cid.connection_of_tunnel),
606 send_broken_without_mqm (sender,
613 /* We are merely a hop on the way, check if we can support the route */
614 next = GCP_get (&pids[off + 1],
616 if ( (NULL == next) ||
617 (GNUNET_NO == GCP_has_core_connection (next)) )
619 /* unworkable, send back BROKEN notification */
620 LOG (GNUNET_ERROR_TYPE_DEBUG,
621 "Received CADET_CONNECTION_CREATE from %s for %s. Next hop %s:%u is down. Sending BROKEN\n",
623 GNUNET_sh2s (&msg->cid.connection_of_tunnel),
624 GNUNET_i2s (&pids[off + 1]),
626 send_broken_without_mqm (sender,
631 if (max_routes <= GNUNET_CONTAINER_multishortmap_size (routes))
633 LOG (GNUNET_ERROR_TYPE_DEBUG,
634 "Received CADET_CONNECTION_CREATE from %s for %s. We have reached our route limit. Sending BROKEN\n",
636 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
637 send_broken_without_mqm (sender,
643 /* Workable route, create routing entry */
644 LOG (GNUNET_ERROR_TYPE_DEBUG,
645 "Received CADET_CONNECTION_CREATE from %s for %s. Next hop %s:%u is up. Creating route\n",
647 GNUNET_sh2s (&msg->cid.connection_of_tunnel),
648 GNUNET_i2s (&pids[off + 1]),
650 route = GNUNET_new (struct CadetRoute);
651 route->options = options;
652 route->cid = msg->cid;
653 route->last_use = GNUNET_TIME_absolute_get ();
654 dir_init (&route->prev,
657 dir_init (&route->next,
660 GNUNET_assert (GNUNET_OK ==
661 GNUNET_CONTAINER_multishortmap_put (routes,
662 &route->cid.connection_of_tunnel,
664 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
665 route->hn = GNUNET_CONTAINER_heap_insert (route_heap,
667 route->last_use.abs_value_us);
668 if (NULL == timeout_task)
669 timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (keepalive_period,
677 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK
679 * @param cls Closure (CadetPeer for neighbor that sent the message).
680 * @param msg Message itself.
683 handle_connection_create_ack (void *cls,
684 const struct GNUNET_CADET_ConnectionCreateAckMessage *msg)
686 struct CadetPeer *peer = cls;
687 struct CadetConnection *cc;
689 /* First, check if ACK belongs to a connection that ends here. */
690 cc = GNUNET_CONTAINER_multishortmap_get (connections,
691 &msg->cid.connection_of_tunnel);
694 /* verify ACK came from the right direction */
695 struct CadetPeerPath *path = GCC_get_path (cc);
698 GCPP_get_peer_at_offset (path,
701 /* received ACK from unexpected direction, ignore! */
705 LOG (GNUNET_ERROR_TYPE_DEBUG,
706 "Received CONNECTION_CREATE_ACK for connection %s.\n",
707 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
708 GCC_handle_connection_create_ack (cc);
712 /* We're just an intermediary peer, route the message along its path */
720 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
722 * @param cls Closure (CadetPeer for neighbor that sent the message).
723 * @param msg Message itself.
724 * @deprecated duplicate logic with #handle_destroy(); dedup!
727 handle_connection_broken (void *cls,
728 const struct GNUNET_CADET_ConnectionBrokenMessage *msg)
730 struct CadetPeer *peer = cls;
731 struct CadetConnection *cc;
732 struct CadetRoute *route;
734 /* First, check if message belongs to a connection that ends here. */
735 cc = GNUNET_CONTAINER_multishortmap_get (connections,
736 &msg->cid.connection_of_tunnel);
739 /* verify message came from the right direction */
740 struct CadetPeerPath *path = GCC_get_path (cc);
743 GCPP_get_peer_at_offset (path,
746 /* received message from unexpected direction, ignore! */
750 LOG (GNUNET_ERROR_TYPE_DEBUG,
751 "Received CONNECTION_BROKEN for connection %s. Destroying it.\n",
752 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
753 GCC_destroy_without_core (cc);
755 /* FIXME: also destroy the path up to the specified link! */
759 /* We're just an intermediary peer, route the message along its path */
760 route = get_route (&msg->cid);
764 destroy_route (route);
765 /* FIXME: also destroy paths we MAY have up to the specified link! */
770 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY
772 * @param cls Closure (CadetPeer for neighbor that sent the message).
773 * @param msg Message itself.
776 handle_connection_destroy (void *cls,
777 const struct GNUNET_CADET_ConnectionDestroyMessage *msg)
779 struct CadetPeer *peer = cls;
780 struct CadetConnection *cc;
781 struct CadetRoute *route;
783 /* First, check if message belongs to a connection that ends here. */
784 cc = GNUNET_CONTAINER_multishortmap_get (connections,
785 &msg->cid.connection_of_tunnel);
788 /* verify message came from the right direction */
789 struct CadetPeerPath *path = GCC_get_path (cc);
792 GCPP_get_peer_at_offset (path,
795 /* received message from unexpected direction, ignore! */
799 LOG (GNUNET_ERROR_TYPE_DEBUG,
800 "Received CONNECTION_DESTROY for connection %s. Destroying connection.\n",
801 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
803 GCC_destroy_without_core (cc);
807 /* We're just an intermediary peer, route the message along its path */
808 LOG (GNUNET_ERROR_TYPE_DEBUG,
809 "Received CONNECTION_DESTROY for connection %s. Destroying route.\n",
810 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
811 route = get_route (&msg->cid);
815 destroy_route (route);
820 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX
822 * @param cls Closure (CadetPeer for neighbor that sent the message).
823 * @param msg Message itself.
826 handle_tunnel_kx (void *cls,
827 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
829 struct CadetPeer *peer = cls;
830 struct CadetConnection *cc;
832 /* First, check if message belongs to a connection that ends here. */
833 cc = GNUNET_CONTAINER_multishortmap_get (connections,
834 &msg->cid.connection_of_tunnel);
837 /* verify message came from the right direction */
838 struct CadetPeerPath *path = GCC_get_path (cc);
841 GCPP_get_peer_at_offset (path,
844 /* received message from unexpected direction, ignore! */
853 /* We're just an intermediary peer, route the message along its path */
861 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH
863 * @param cls Closure (CadetPeer for neighbor that sent the message).
864 * @param msg Message itself.
867 handle_tunnel_kx_auth (void *cls,
868 const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
870 struct CadetPeer *peer = cls;
871 struct CadetConnection *cc;
873 /* First, check if message belongs to a connection that ends here. */
874 cc = GNUNET_CONTAINER_multishortmap_get (connections,
875 &msg->kx.cid.connection_of_tunnel);
878 /* verify message came from the right direction */
879 struct CadetPeerPath *path = GCC_get_path (cc);
882 GCPP_get_peer_at_offset (path,
885 /* received message from unexpected direction, ignore! */
889 GCC_handle_kx_auth (cc,
894 /* We're just an intermediary peer, route the message along its path */
902 * Check if the encrypted message has the appropriate size.
904 * @param cls Closure (unused).
905 * @param msg Message to check.
907 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
910 check_tunnel_encrypted (void *cls,
911 const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
918 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED.
920 * @param cls Closure (CadetPeer for neighbor that sent the message).
921 * @param msg Message itself.
924 handle_tunnel_encrypted (void *cls,
925 const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
927 struct CadetPeer *peer = cls;
928 struct CadetConnection *cc;
930 /* First, check if message belongs to a connection that ends here. */
931 cc = GNUNET_CONTAINER_multishortmap_get (connections,
932 &msg->cid.connection_of_tunnel);
935 /* verify message came from the right direction */
936 struct CadetPeerPath *path = GCC_get_path (cc);
939 GCPP_get_peer_at_offset (path,
942 /* received message from unexpected direction, ignore! */
946 GCC_handle_encrypted (cc,
950 /* We're just an intermediary peer, route the message along its path */
958 * Function called after #GNUNET_CORE_connect has succeeded (or failed
959 * for good). Note that the private key of the peer is intentionally
960 * not exposed here; if you need it, your process should try to read
961 * the private key file directly (which should work if you are
962 * authorized...). Implementations of this function must not call
963 * #GNUNET_CORE_disconnect (other than by scheduling a new task to
967 * @param my_identity ID of this peer, NULL if we failed
970 core_init_cb (void *cls,
971 const struct GNUNET_PeerIdentity *my_identity)
973 if (NULL == my_identity)
981 sizeof (struct GNUNET_PeerIdentity)));
986 * Method called whenever a given peer connects.
989 * @param peer peer identity this notification is about
992 core_connect_cb (void *cls,
993 const struct GNUNET_PeerIdentity *peer,
994 struct GNUNET_MQ_Handle *mq)
996 struct CadetPeer *cp;
998 LOG (GNUNET_ERROR_TYPE_DEBUG,
999 "CORE connection to peer %s was established.\n",
1010 * Method called whenever a peer disconnects.
1012 * @param cls closure
1013 * @param peer peer identity this notification is about
1016 core_disconnect_cb (void *cls,
1017 const struct GNUNET_PeerIdentity *peer,
1020 struct CadetPeer *cp = peer_cls;
1022 LOG (GNUNET_ERROR_TYPE_DEBUG,
1023 "CORE connection to peer %s went down.\n",
1031 * Initialize the CORE subsystem.
1033 * @param c Configuration.
1036 GCO_init (const struct GNUNET_CONFIGURATION_Handle *c)
1038 struct GNUNET_MQ_MessageHandler handlers[] = {
1039 GNUNET_MQ_hd_var_size (connection_create,
1040 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE,
1041 struct GNUNET_CADET_ConnectionCreateMessage,
1043 GNUNET_MQ_hd_fixed_size (connection_create_ack,
1044 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK,
1045 struct GNUNET_CADET_ConnectionCreateAckMessage,
1047 GNUNET_MQ_hd_fixed_size (connection_broken,
1048 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN,
1049 struct GNUNET_CADET_ConnectionBrokenMessage,
1051 GNUNET_MQ_hd_fixed_size (connection_destroy,
1052 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY,
1053 struct GNUNET_CADET_ConnectionDestroyMessage,
1055 GNUNET_MQ_hd_fixed_size (tunnel_kx,
1056 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX,
1057 struct GNUNET_CADET_TunnelKeyExchangeMessage,
1059 GNUNET_MQ_hd_fixed_size (tunnel_kx_auth,
1060 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH,
1061 struct GNUNET_CADET_TunnelKeyExchangeAuthMessage,
1063 GNUNET_MQ_hd_var_size (tunnel_encrypted,
1064 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED,
1065 struct GNUNET_CADET_TunnelEncryptedMessage,
1067 GNUNET_MQ_handler_end ()
1071 GNUNET_CONFIGURATION_get_value_number (c,
1076 routes = GNUNET_CONTAINER_multishortmap_create (1024,
1078 route_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1079 core = GNUNET_CORE_connect (c,
1083 &core_disconnect_cb,
1089 * Shut down the CORE subsystem.
1096 GNUNET_CORE_disconnect (core);
1099 GNUNET_assert (0 == GNUNET_CONTAINER_multishortmap_size (routes));
1100 GNUNET_CONTAINER_multishortmap_destroy (routes);
1102 GNUNET_CONTAINER_heap_destroy (route_heap);
1104 if (NULL != timeout_task)
1106 GNUNET_SCHEDULER_cancel (timeout_task);
1107 timeout_task = NULL;
1111 /* end of gnunet-cadet-service_core.c */