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 * - Optimization: given BROKEN messages, destroy paths (?)
34 #include "gnunet-service-cadet-new_core.h"
35 #include "gnunet-service-cadet-new_paths.h"
36 #include "gnunet-service-cadet-new_peer.h"
37 #include "gnunet-service-cadet-new_connection.h"
38 #include "gnunet-service-cadet-new_tunnels.h"
39 #include "gnunet_core_service.h"
40 #include "gnunet_statistics_service.h"
41 #include "cadet_protocol.h"
44 #define LOG(level, ...) GNUNET_log_from(level,"cadet-cor",__VA_ARGS__)
48 * Number of messages we are willing to buffer per route.
50 #define ROUTE_BUFFER_SIZE 8
54 * Information we keep per direction for a route.
61 struct CadetPeer *hop;
64 * Route this direction is part of.
66 struct CadetRoute *my_route;
69 * Message queue manager for @e hop.
71 struct GCP_MessageQueueManager *mqm;
74 * Cyclic message buffer to @e hop.
76 struct GNUNET_MQ_Envelope *out_buffer[ROUTE_BUFFER_SIZE];
79 * Next write offset to use to append messages to @e out_buffer.
81 unsigned int out_wpos;
84 * Next read offset to use to retrieve messages from @e out_buffer.
86 unsigned int out_rpos;
89 * Is @e mqm currently ready for transmission?
97 * Description of a segment of a `struct CadetConnection` at the
98 * intermediate peers. Routes are basically entries in a peer's
99 * routing table for forwarding traffic. At both endpoints, the
100 * routes are terminated by a `struct CadetConnection`, which knows
101 * the complete `struct CadetPath` that is formed by the individual
108 * Information about the next hop on this route.
110 struct RouteDirection next;
113 * Information about the previous hop on this route.
115 struct RouteDirection prev;
118 * Unique identifier for the connection that uses this route.
120 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
123 * When was this route last in use?
125 struct GNUNET_TIME_Absolute last_use;
128 * Position of this route in the #route_heap.
130 struct GNUNET_CONTAINER_HeapNode *hn;
135 * Handle to the CORE service.
137 static struct GNUNET_CORE_Handle *core;
140 * Routes on which this peer is an intermediate.
142 static struct GNUNET_CONTAINER_MultiShortmap *routes;
145 * Heap of routes, MIN-sorted by last activity.
147 static struct GNUNET_CONTAINER_Heap *route_heap;
150 * Maximum number of concurrent routes this peer will support.
152 static unsigned long long max_routes;
155 * Task to timeout routes.
157 static struct GNUNET_SCHEDULER_Task *timeout_task;
161 * Get the route corresponding to a hash.
163 * @param cid hash generated from the connection identifier
165 static struct CadetRoute *
166 get_route (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
168 return GNUNET_CONTAINER_multishortmap_get (routes,
169 &cid->connection_of_tunnel);
174 * We message @a msg from @a prev. Find its route by @a cid and
175 * forward to the next hop. Drop and signal broken route if we do not
178 * @param prev previous hop (sender)
179 * @param cid connection identifier, tells us which route to use
180 * @param msg the message to forward
183 route_message (struct CadetPeer *prev,
184 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
185 const struct GNUNET_MessageHeader *msg)
187 struct CadetRoute *route;
188 struct RouteDirection *dir;
189 struct GNUNET_MQ_Envelope *env;
191 route = get_route (cid);
194 struct GNUNET_MQ_Envelope *env;
195 struct GNUNET_CADET_ConnectionBrokenMessage *bm;
197 LOG (GNUNET_ERROR_TYPE_DEBUG,
198 "Failed to route message of type %u from %s on connection %s: no route\n",
201 GNUNET_sh2s (&cid->connection_of_tunnel));
202 env = GNUNET_MQ_msg (bm,
203 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
205 bm->peer1 = my_full_id;
210 route->last_use = GNUNET_TIME_absolute_get ();
211 GNUNET_CONTAINER_heap_update_cost (route->hn,
212 route->last_use.abs_value_us);
213 dir = (prev == route->prev.hop) ? &route->next : &route->prev;
214 if (GNUNET_YES == dir->is_ready)
216 LOG (GNUNET_ERROR_TYPE_DEBUG,
217 "Routing message of type %u from %s to %s on connection %s\n",
220 GNUNET_i2s (GCP_get_id (dir->hop)),
221 GNUNET_sh2s (&cid->connection_of_tunnel));
222 dir->is_ready = GNUNET_NO;
224 GNUNET_MQ_msg_copy (msg));
227 env = dir->out_buffer[dir->out_wpos];
230 /* Queue full, drop earliest message in queue */
231 LOG (GNUNET_ERROR_TYPE_DEBUG,
232 "Queue full due to new message of type %u from %s to %s on connection %s, dropping old message\n",
235 GNUNET_i2s (GCP_get_id (dir->hop)),
236 GNUNET_sh2s (&cid->connection_of_tunnel));
237 GNUNET_STATISTICS_update (stats,
238 "# messages dropped due to full buffer",
241 GNUNET_assert (dir->out_rpos == dir->out_wpos);
242 GNUNET_MQ_discard (env);
244 if (ROUTE_BUFFER_SIZE == dir->out_rpos)
247 LOG (GNUNET_ERROR_TYPE_DEBUG,
248 "Queueing new message of type %u from %s to %s on connection %s\n",
251 GNUNET_i2s (GCP_get_id (dir->hop)),
252 GNUNET_sh2s (&cid->connection_of_tunnel));
253 env = GNUNET_MQ_msg_copy (msg);
254 dir->out_buffer[dir->out_wpos] = env;
256 if (ROUTE_BUFFER_SIZE == dir->out_wpos)
262 * Check if the create_connection message has the appropriate size.
264 * @param cls Closure (unused).
265 * @param msg Message to check.
267 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
270 check_connection_create (void *cls,
271 const struct GNUNET_CADET_ConnectionCreateMessage *msg)
273 uint16_t size = ntohs (msg->header.size) - sizeof (*msg);
275 if (0 != (size % sizeof (struct GNUNET_PeerIdentity)))
285 * Free internal data of a route direction.
287 * @param dir direction to destroy (do NOT free memory of 'dir' itself)
290 destroy_direction (struct RouteDirection *dir)
292 for (unsigned int i=0;i<ROUTE_BUFFER_SIZE;i++)
293 if (NULL != dir->out_buffer[i])
295 GNUNET_MQ_discard (dir->out_buffer[i]);
296 dir->out_buffer[i] = NULL;
298 if (NULL != dir->mqm)
300 GCP_request_mq_cancel (dir->mqm,
308 * Destroy our state for @a route.
310 * @param route route to destroy
313 destroy_route (struct CadetRoute *route)
315 LOG (GNUNET_ERROR_TYPE_DEBUG,
316 "Destroying route from %s to %s of connection %s\n",
317 GNUNET_i2s (GCP_get_id (route->prev.hop)),
318 GNUNET_i2s2 (GCP_get_id (route->next.hop)),
319 GNUNET_sh2s (&route->cid.connection_of_tunnel));
320 GNUNET_assert (route ==
321 GNUNET_CONTAINER_heap_remove_node (route->hn));
322 destroy_direction (&route->prev);
323 destroy_direction (&route->next);
329 * Send message that a route is broken between @a peer1 and @a peer2.
331 * @param target where to send the message
332 * @param cid connection identifier to use
333 * @param peer1 one of the peers where a link is broken
334 * @param peer2 another one of the peers where a link is broken
337 send_broken (struct RouteDirection *target,
338 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
339 const struct GNUNET_PeerIdentity *peer1,
340 const struct GNUNET_PeerIdentity *peer2)
342 struct GNUNET_MQ_Envelope *env;
343 struct GNUNET_CADET_ConnectionBrokenMessage *bm;
345 if (NULL == target->mqm)
346 return; /* Can't send notification, connection is down! */
347 LOG (GNUNET_ERROR_TYPE_DEBUG,
348 "Notifying %s about BROKEN route at %s-%s of connection %s\n",
349 GCP_2s (target->hop),
352 GNUNET_sh2s (&cid->connection_of_tunnel));
354 env = GNUNET_MQ_msg (bm,
355 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
362 GCP_request_mq_cancel (target->mqm,
369 * Function called to check if any routes have timed out, and if
370 * so, to clean them up. Finally, schedules itself again at the
371 * earliest time where there might be more work.
376 timeout_cb (void *cls)
378 struct CadetRoute *r;
379 struct GNUNET_TIME_Relative linger;
380 struct GNUNET_TIME_Absolute exp;
383 linger = GNUNET_TIME_relative_multiply (keepalive_period,
385 while (NULL != (r = GNUNET_CONTAINER_heap_peek (route_heap)))
387 exp = GNUNET_TIME_absolute_add (r->last_use,
389 if (0 != GNUNET_TIME_absolute_get_duration (exp).rel_value_us)
391 /* Route not yet timed out, wait until it does. */
392 timeout_task = GNUNET_SCHEDULER_add_at (exp,
397 send_broken (&r->prev,
401 send_broken (&r->next,
407 /* No more routes left, so no need for a #timeout_task */
412 * Function called when the message queue to the previous hop
413 * becomes available/unavailable. We expect this function to
414 * be called immediately when we register, and then again
415 * later if the connection ever goes down.
417 * @param cls the `struct RouteDirection`
418 * @param available #GNUNET_YES if sending is now possible,
419 * #GNUNET_NO if sending is no longer possible
420 * #GNUNET_SYSERR if sending is no longer possible
421 * and the last envelope was discarded
424 dir_ready_cb (void *cls,
427 struct RouteDirection *dir = cls;
428 struct CadetRoute *route = dir->my_route;
429 struct RouteDirection *odir;
431 if (GNUNET_YES == ready)
433 struct GNUNET_MQ_Envelope *env;
435 dir->is_ready = GNUNET_YES;
436 if (NULL != (env = dir->out_buffer[dir->out_rpos]))
438 dir->out_buffer[dir->out_rpos] = NULL;
440 if (ROUTE_BUFFER_SIZE == dir->out_rpos)
442 dir->is_ready = GNUNET_NO;
448 odir = (dir == &route->next) ? &route->prev : &route->next;
449 send_broken (&route->next,
451 GCP_get_id (odir->hop),
453 destroy_route (route);
458 * Initialize one of the directions of a route.
460 * @param route route the direction belongs to
461 * @param dir direction to initialize
462 * @param hop next hop on in the @a dir
465 dir_init (struct RouteDirection *dir,
466 struct CadetRoute *route,
467 struct CadetPeer *hop)
470 dir->my_route = route;
471 dir->mqm = GCP_request_mq (hop,
474 GNUNET_assert (GNUNET_YES == dir->is_ready);
479 * We could not create the desired route. Send a
480 * #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
481 * message to @a target.
483 * @param target who should receive the message
484 * @param cid identifier of the connection/route that failed
485 * @param failure_at neighbour with which we failed to route,
489 send_broken_without_mqm (struct CadetPeer *target,
490 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
491 const struct GNUNET_PeerIdentity *failure_at)
493 struct GNUNET_MQ_Envelope *env;
494 struct GNUNET_CADET_ConnectionBrokenMessage *bm;
496 env = GNUNET_MQ_msg (bm,
497 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
499 bm->peer1 = my_full_id;
500 if (NULL != failure_at)
501 bm->peer2 = *failure_at;
502 GCP_send_ooo (target,
508 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE
510 * @param cls Closure (CadetPeer for neighbor that sent the message).
511 * @param msg Message itself.
514 handle_connection_create (void *cls,
515 const struct GNUNET_CADET_ConnectionCreateMessage *msg)
517 struct CadetPeer *sender = cls;
518 struct CadetPeer *next;
519 const struct GNUNET_PeerIdentity *pids = (const struct GNUNET_PeerIdentity *) &msg[1];
520 struct CadetRoute *route;
521 uint16_t size = ntohs (msg->header.size) - sizeof (*msg);
522 unsigned int path_length;
525 path_length = size / sizeof (struct GNUNET_PeerIdentity);
526 /* Initiator is at offset 0. */
527 for (off=1;off<path_length;off++)
528 if (0 == memcmp (&my_full_id,
530 sizeof (struct GNUNET_PeerIdentity)))
532 if (off == path_length)
534 /* We are not on the path, bogus request */
538 /* Check previous hop */
539 if (sender != GCP_get (&pids[off - 1],
542 /* sender is not on the path, not allowed */
547 get_route (&msg->cid))
549 /* Duplicate CREATE, pass it on, previous one might have been lost! */
550 LOG (GNUNET_ERROR_TYPE_DEBUG,
551 "Passing on duplicate CADET_CONNECTION_CREATE message on connection %s\n",
552 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
553 route_message (sender,
558 if (off == path_length - 1)
560 /* We are the destination, create connection */
561 struct CadetConnection *cc;
562 struct CadetPeerPath *path;
563 struct CadetPeer *origin;
565 cc = GNUNET_CONTAINER_multishortmap_get (connections,
566 &msg->cid.connection_of_tunnel);
569 LOG (GNUNET_ERROR_TYPE_DEBUG,
570 "Received duplicate CADET_CONNECTION_CREATE message on connection %s\n",
571 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
572 GCC_handle_duplicate_create (cc);
576 origin = GCP_get (&pids[0],
578 LOG (GNUNET_ERROR_TYPE_DEBUG,
579 "Received CADET_CONNECTION_CREATE message from %s for connection %s, building inverse path\n",
581 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
582 path = GCPP_get_path_from_route (path_length - 1,
585 GCT_add_inbound_connection (GCP_get_tunnel (origin,
590 /* Send back BROKEN: duplicate connection on the same path,
591 we will use the other one. */
592 LOG (GNUNET_ERROR_TYPE_DEBUG,
593 "Received CADET_CONNECTION_CREATE from %s for %s, but %s already has a connection. Sending BROKEN\n",
595 GNUNET_sh2s (&msg->cid.connection_of_tunnel),
597 send_broken_without_mqm (sender,
604 /* We are merely a hop on the way, check if we can support the route */
605 next = GCP_get (&pids[off + 1],
607 if ( (NULL == next) ||
608 (GNUNET_NO == GCP_has_core_connection (next)) )
610 /* unworkable, send back BROKEN notification */
611 LOG (GNUNET_ERROR_TYPE_DEBUG,
612 "Received CADET_CONNECTION_CREATE from %s for %s. Next hop %s:%u is down. Sending BROKEN\n",
614 GNUNET_sh2s (&msg->cid.connection_of_tunnel),
615 GNUNET_i2s (&pids[off + 1]),
617 send_broken_without_mqm (sender,
622 if (max_routes <= GNUNET_CONTAINER_multishortmap_size (routes))
624 LOG (GNUNET_ERROR_TYPE_DEBUG,
625 "Received CADET_CONNECTION_CREATE from %s for %s. We have reached our route limit. Sending BROKEN\n",
627 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
628 send_broken_without_mqm (sender,
634 /* Workable route, create routing entry */
635 LOG (GNUNET_ERROR_TYPE_DEBUG,
636 "Received CADET_CONNECTION_CREATE from %s for %s. Next hop %s:%u is up. Creating route\n",
638 GNUNET_sh2s (&msg->cid.connection_of_tunnel),
639 GNUNET_i2s (&pids[off + 1]),
641 route = GNUNET_new (struct CadetRoute);
642 route->cid = msg->cid;
643 route->last_use = GNUNET_TIME_absolute_get ();
644 dir_init (&route->prev,
647 dir_init (&route->next,
650 GNUNET_assert (GNUNET_OK ==
651 GNUNET_CONTAINER_multishortmap_put (routes,
652 &route->cid.connection_of_tunnel,
654 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
655 route->hn = GNUNET_CONTAINER_heap_insert (route_heap,
657 route->last_use.abs_value_us);
658 if (NULL == timeout_task)
659 timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (keepalive_period,
667 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK
669 * @param cls Closure (CadetPeer for neighbor that sent the message).
670 * @param msg Message itself.
673 handle_connection_create_ack (void *cls,
674 const struct GNUNET_CADET_ConnectionCreateAckMessage *msg)
676 struct CadetPeer *peer = cls;
677 struct CadetConnection *cc;
679 /* First, check if ACK belongs to a connection that ends here. */
680 cc = GNUNET_CONTAINER_multishortmap_get (connections,
681 &msg->cid.connection_of_tunnel);
684 /* verify ACK came from the right direction */
685 struct CadetPeerPath *path = GCC_get_path (cc);
688 GCPP_get_peer_at_offset (path,
691 /* received ACK from unexpected direction, ignore! */
695 LOG (GNUNET_ERROR_TYPE_DEBUG,
696 "Received CONNECTION_CREATE_ACK for connection %s.\n",
697 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
698 GCC_handle_connection_create_ack (cc);
702 /* We're just an intermediary peer, route the message along its path */
710 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
712 * @param cls Closure (CadetPeer for neighbor that sent the message).
713 * @param msg Message itself.
714 * @deprecated duplicate logic with #handle_destroy(); dedup!
717 handle_connection_broken (void *cls,
718 const struct GNUNET_CADET_ConnectionBrokenMessage *msg)
720 struct CadetPeer *peer = cls;
721 struct CadetConnection *cc;
722 struct CadetRoute *route;
724 /* First, check if message belongs to a connection that ends here. */
725 cc = GNUNET_CONTAINER_multishortmap_get (connections,
726 &msg->cid.connection_of_tunnel);
729 /* verify message came from the right direction */
730 struct CadetPeerPath *path = GCC_get_path (cc);
733 GCPP_get_peer_at_offset (path,
736 /* received message from unexpected direction, ignore! */
740 LOG (GNUNET_ERROR_TYPE_DEBUG,
741 "Received CONNECTION_BROKEN for connection %s. Destroying it.\n",
742 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
743 GCC_destroy_without_core (cc);
745 /* FIXME: also destroy the path up to the specified link! */
749 /* We're just an intermediary peer, route the message along its path */
750 route = get_route (&msg->cid);
754 destroy_route (route);
755 /* FIXME: also destroy paths we MAY have up to the specified link! */
760 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY
762 * @param cls Closure (CadetPeer for neighbor that sent the message).
763 * @param msg Message itself.
766 handle_connection_destroy (void *cls,
767 const struct GNUNET_CADET_ConnectionDestroyMessage *msg)
769 struct CadetPeer *peer = cls;
770 struct CadetConnection *cc;
771 struct CadetRoute *route;
773 /* First, check if message belongs to a connection that ends here. */
774 cc = GNUNET_CONTAINER_multishortmap_get (connections,
775 &msg->cid.connection_of_tunnel);
778 /* verify message came from the right direction */
779 struct CadetPeerPath *path = GCC_get_path (cc);
782 GCPP_get_peer_at_offset (path,
785 /* received message from unexpected direction, ignore! */
789 LOG (GNUNET_ERROR_TYPE_DEBUG,
790 "Received CONNECTION_DESTROY for connection %s. Destroying connection.\n",
791 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
793 GCC_destroy_without_core (cc);
797 /* We're just an intermediary peer, route the message along its path */
798 LOG (GNUNET_ERROR_TYPE_DEBUG,
799 "Received CONNECTION_DESTROY for connection %s. Destroying route.\n",
800 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
801 route = get_route (&msg->cid);
805 destroy_route (route);
810 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX
812 * @param cls Closure (CadetPeer for neighbor that sent the message).
813 * @param msg Message itself.
816 handle_tunnel_kx (void *cls,
817 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
819 struct CadetPeer *peer = cls;
820 struct CadetConnection *cc;
822 /* First, check if message belongs to a connection that ends here. */
823 cc = GNUNET_CONTAINER_multishortmap_get (connections,
824 &msg->cid.connection_of_tunnel);
827 /* verify message came from the right direction */
828 struct CadetPeerPath *path = GCC_get_path (cc);
831 GCPP_get_peer_at_offset (path,
834 /* received message from unexpected direction, ignore! */
843 /* We're just an intermediary peer, route the message along its path */
851 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH
853 * @param cls Closure (CadetPeer for neighbor that sent the message).
854 * @param msg Message itself.
857 handle_tunnel_kx_auth (void *cls,
858 const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
860 struct CadetPeer *peer = cls;
861 struct CadetConnection *cc;
863 /* First, check if message belongs to a connection that ends here. */
864 cc = GNUNET_CONTAINER_multishortmap_get (connections,
865 &msg->kx.cid.connection_of_tunnel);
868 /* verify message came from the right direction */
869 struct CadetPeerPath *path = GCC_get_path (cc);
872 GCPP_get_peer_at_offset (path,
875 /* received message from unexpected direction, ignore! */
879 GCC_handle_kx_auth (cc,
884 /* We're just an intermediary peer, route the message along its path */
892 * Check if the encrypted message has the appropriate size.
894 * @param cls Closure (unused).
895 * @param msg Message to check.
897 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
900 check_tunnel_encrypted (void *cls,
901 const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
908 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED.
910 * @param cls Closure (CadetPeer for neighbor that sent the message).
911 * @param msg Message itself.
914 handle_tunnel_encrypted (void *cls,
915 const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
917 struct CadetPeer *peer = cls;
918 struct CadetConnection *cc;
920 /* First, check if message belongs to a connection that ends here. */
921 cc = GNUNET_CONTAINER_multishortmap_get (connections,
922 &msg->cid.connection_of_tunnel);
925 /* verify message came from the right direction */
926 struct CadetPeerPath *path = GCC_get_path (cc);
929 GCPP_get_peer_at_offset (path,
932 /* received message from unexpected direction, ignore! */
936 GCC_handle_encrypted (cc,
940 /* We're just an intermediary peer, route the message along its path */
948 * Function called after #GNUNET_CORE_connect has succeeded (or failed
949 * for good). Note that the private key of the peer is intentionally
950 * not exposed here; if you need it, your process should try to read
951 * the private key file directly (which should work if you are
952 * authorized...). Implementations of this function must not call
953 * #GNUNET_CORE_disconnect (other than by scheduling a new task to
957 * @param my_identity ID of this peer, NULL if we failed
960 core_init_cb (void *cls,
961 const struct GNUNET_PeerIdentity *my_identity)
963 if (NULL == my_identity)
971 sizeof (struct GNUNET_PeerIdentity)));
976 * Method called whenever a given peer connects.
979 * @param peer peer identity this notification is about
982 core_connect_cb (void *cls,
983 const struct GNUNET_PeerIdentity *peer,
984 struct GNUNET_MQ_Handle *mq)
986 struct CadetPeer *cp;
988 LOG (GNUNET_ERROR_TYPE_DEBUG,
989 "CORE connection to peer %s was established.\n",
1000 * Method called whenever a peer disconnects.
1002 * @param cls closure
1003 * @param peer peer identity this notification is about
1006 core_disconnect_cb (void *cls,
1007 const struct GNUNET_PeerIdentity *peer,
1010 struct CadetPeer *cp = peer_cls;
1012 LOG (GNUNET_ERROR_TYPE_DEBUG,
1013 "CORE connection to peer %s went down.\n",
1021 * Initialize the CORE subsystem.
1023 * @param c Configuration.
1026 GCO_init (const struct GNUNET_CONFIGURATION_Handle *c)
1028 struct GNUNET_MQ_MessageHandler handlers[] = {
1029 GNUNET_MQ_hd_var_size (connection_create,
1030 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE,
1031 struct GNUNET_CADET_ConnectionCreateMessage,
1033 GNUNET_MQ_hd_fixed_size (connection_create_ack,
1034 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK,
1035 struct GNUNET_CADET_ConnectionCreateAckMessage,
1037 GNUNET_MQ_hd_fixed_size (connection_broken,
1038 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN,
1039 struct GNUNET_CADET_ConnectionBrokenMessage,
1041 GNUNET_MQ_hd_fixed_size (connection_destroy,
1042 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY,
1043 struct GNUNET_CADET_ConnectionDestroyMessage,
1045 GNUNET_MQ_hd_fixed_size (tunnel_kx,
1046 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX,
1047 struct GNUNET_CADET_TunnelKeyExchangeMessage,
1049 GNUNET_MQ_hd_fixed_size (tunnel_kx_auth,
1050 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH,
1051 struct GNUNET_CADET_TunnelKeyExchangeAuthMessage,
1053 GNUNET_MQ_hd_var_size (tunnel_encrypted,
1054 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED,
1055 struct GNUNET_CADET_TunnelEncryptedMessage,
1057 GNUNET_MQ_handler_end ()
1061 GNUNET_CONFIGURATION_get_value_number (c,
1066 routes = GNUNET_CONTAINER_multishortmap_create (1024,
1068 route_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1069 core = GNUNET_CORE_connect (c,
1073 &core_disconnect_cb,
1079 * Shut down the CORE subsystem.
1086 GNUNET_CORE_disconnect (core);
1089 GNUNET_assert (0 == GNUNET_CONTAINER_multishortmap_size (routes));
1090 GNUNET_CONTAINER_multishortmap_destroy (routes);
1092 GNUNET_CONTAINER_heap_destroy (route_heap);
1094 if (NULL != timeout_task)
1096 GNUNET_SCHEDULER_cancel (timeout_task);
1097 timeout_task = NULL;
1101 /* end of gnunet-cadet-service_core.c */