2 This file is part of GNUnet.
3 Copyright (C) 2001-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-new_connection.c
23 * @brief management of CORE-level end-to-end connections; establishes
24 * end-to-end routes and transmits messages along the route
25 * @author Bartlomiej Polot
26 * @author Christian Grothoff
29 * - keep per-connection performance metrics
30 * - in particular, interact with channel (!) to see
31 * if we get ACKs indicating successful payload delivery.
34 #include "gnunet-service-cadet-new.h"
35 #include "gnunet-service-cadet-new_channel.h"
36 #include "gnunet-service-cadet-new_connection.h"
37 #include "gnunet-service-cadet-new_paths.h"
38 #include "gnunet-service-cadet-new_peer.h"
39 #include "gnunet-service-cadet-new_tunnels.h"
40 #include "gnunet_cadet_service.h"
41 #include "gnunet_statistics_service.h"
42 #include "cadet_protocol.h"
45 #define LOG(level, ...) GNUNET_log_from(level,"cadet-con",__VA_ARGS__)
49 * All the states a connection can be in.
51 enum CadetConnectionState
54 * Uninitialized status, we have not yet even gotten the message queue.
59 * Connection create message in queue, awaiting transmission by CORE.
61 CADET_CONNECTION_SENDING_CREATE,
64 * Connection create message sent, waiting for ACK.
66 CADET_CONNECTION_SENT,
69 * We are an inbound connection, and received a CREATE. Need to
70 * send an CREATE_ACK back.
72 CADET_CONNECTION_CREATE_RECEIVED,
75 * Connection confirmed, ready to carry traffic.
77 CADET_CONNECTION_READY
83 * Low-level connection to a destination.
85 struct CadetConnection
89 * ID of the connection.
91 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
94 * To which peer does this connection go?
96 struct CadetPeer *destination;
99 * Which tunnel is using this connection?
101 struct CadetTConnection *ct;
104 * Path we are using to our destination.
106 struct CadetPeerPath *path;
109 * Pending message, NULL if we are ready to transmit.
111 struct GNUNET_MQ_Envelope *env;
114 * Handle for calling #GCP_request_mq_cancel() once we are finished.
116 struct GCP_MessageQueueManager *mq_man;
119 * Task for connection maintenance.
121 struct GNUNET_SCHEDULER_Task *task;
124 * Queue entry for keepalive messages.
126 struct CadetTunnelQueueEntry *keepalive_qe;
129 * Function to call once we are ready to transmit.
131 GCC_ReadyCallback ready_cb;
134 * Closure for @e ready_cb.
139 * How long do we wait before we try again with a CREATE message?
141 struct GNUNET_TIME_Relative retry_delay;
144 * State of the connection.
146 enum CadetConnectionState state;
149 * Offset of our @e destination in @e path.
154 * Are we ready to transmit via @e mq_man right now?
162 * Update the connection state. Also triggers the necessary
165 * @param cc connection to update the state for
166 * @param new_state new state for @a cc
167 * @param new_mqm_ready new `mqm_ready` state for @a cc
170 update_state (struct CadetConnection *cc,
171 enum CadetConnectionState new_state,
177 if ( (new_state == cc->state) &&
178 (new_mqm_ready == cc->mqm_ready) )
179 return; /* no change, nothing to do */
180 old_ready = ( (CADET_CONNECTION_READY == cc->state) &&
181 (GNUNET_YES == cc->mqm_ready) );
182 new_ready = ( (CADET_CONNECTION_READY == new_state) &&
183 (GNUNET_YES == new_mqm_ready) );
184 cc->state = new_state;
185 cc->mqm_ready = new_mqm_ready;
186 if (old_ready != new_ready)
187 cc->ready_cb (cc->ready_cb_cls,
193 * Destroy a connection, part of the internal implementation. Called
194 * only from #GCC_destroy_from_core() or #GCC_destroy_from_tunnel().
196 * @param cc connection to destroy
199 GCC_destroy (struct CadetConnection *cc)
201 LOG (GNUNET_ERROR_TYPE_DEBUG,
204 if (NULL != cc->mq_man)
206 GCP_request_mq_cancel (cc->mq_man,
210 if (NULL != cc->task)
212 GNUNET_SCHEDULER_cancel (cc->task);
215 if (NULL != cc->keepalive_qe)
217 GCT_send_cancel (cc->keepalive_qe);
218 cc->keepalive_qe = NULL;
220 GCPP_del_connection (cc->path,
223 GNUNET_assert (GNUNET_YES ==
224 GNUNET_CONTAINER_multishortmap_remove (connections,
225 &GCC_get_id (cc)->connection_of_tunnel,
233 * Destroy a connection, called when the CORE layer is already done
234 * (i.e. has received a BROKEN message), but if we still have to
235 * communicate the destruction of the connection to the tunnel (if one
238 * @param cc connection to destroy
241 GCC_destroy_without_core (struct CadetConnection *cc)
245 GCT_connection_lost (cc->ct);
253 * Destroy a connection, called if the tunnel association with the
254 * connection was already broken, but we still need to notify the CORE
255 * layer about the breakage.
257 * @param cc connection to destroy
260 GCC_destroy_without_tunnel (struct CadetConnection *cc)
263 if ( (CADET_CONNECTION_SENDING_CREATE != cc->state) &&
264 (NULL != cc->mq_man) )
266 struct GNUNET_MQ_Envelope *env;
267 struct GNUNET_CADET_ConnectionDestroyMessage *destroy_msg;
269 /* Need to notify next hop that we are down. */
270 env = GNUNET_MQ_msg (destroy_msg,
271 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY);
272 destroy_msg->cid = cc->cid;
273 GCP_request_mq_cancel (cc->mq_man,
282 * Return the tunnel associated with this connection.
284 * @param cc connection to query
285 * @return corresponding entry in the tunnel's connection list
287 struct CadetTConnection *
288 GCC_get_ct (struct CadetConnection *cc)
295 * Send a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE through the
296 * tunnel to prevent it from timing out.
298 * @param cls the `struct CadetConnection` to keep alive.
301 send_keepalive (void *cls);
305 * Keepalive was transmitted. Remember this, and possibly
306 * schedule the next one.
308 * @param cls the `struct CadetConnection` to keep alive.
311 keepalive_done (void *cls)
313 struct CadetConnection *cc = cls;
315 cc->keepalive_qe = NULL;
316 if ( (GNUNET_YES == cc->mqm_ready) &&
318 cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
325 * Send a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE through the
326 * tunnel to prevent it from timing out.
328 * @param cls the `struct CadetConnection` to keep alive.
331 send_keepalive (void *cls)
333 struct CadetConnection *cc = cls;
334 struct GNUNET_MessageHeader msg;
337 if (CADET_TUNNEL_KEY_OK != GCT_get_estate (cc->ct->t))
339 /* Tunnel not yet ready, wait with keepalives... */
340 cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
345 GNUNET_assert (NULL != cc->ct);
346 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
347 GNUNET_assert (NULL == cc->keepalive_qe);
348 LOG (GNUNET_ERROR_TYPE_INFO,
349 "Sending KEEPALIVE on behalf of %s via %s\n",
352 GNUNET_STATISTICS_update (stats,
356 msg.size = htons (sizeof (msg));
357 msg.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE);
360 = GCT_send (cc->ct->t,
368 * A #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK was received for this connection, implying
369 * that the end-to-end connection is up. Process it.
371 * @param cc the connection that got the ACK.
374 GCC_handle_connection_create_ack (struct CadetConnection *cc)
376 LOG (GNUNET_ERROR_TYPE_DEBUG,
377 "Received CADET_CONNECTION_CREATE_ACK for %s in state %d (%s)\n",
380 (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy");
381 if (CADET_CONNECTION_READY == cc->state)
382 return; /* Duplicate ACK, ignore */
383 if (NULL != cc->task)
385 GNUNET_SCHEDULER_cancel (cc->task);
389 CADET_CONNECTION_READY,
391 if ( (NULL == cc->keepalive_qe) &&
392 (GNUNET_YES == cc->mqm_ready) &&
394 cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
403 * @param cc connection that received encrypted message
404 * @param msg the key exchange message
407 GCC_handle_kx (struct CadetConnection *cc,
408 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
410 if (CADET_CONNECTION_SENT == cc->state)
412 /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
413 clearly something is working, so pretend we got an ACK. */
414 LOG (GNUNET_ERROR_TYPE_DEBUG,
415 "Faking connection CADET_CONNECTION_CREATE_ACK for %s due to KX\n",
417 GCC_handle_connection_create_ack (cc);
419 GCT_handle_kx (cc->ct,
425 * Handle KX_AUTH message.
427 * @param cc connection that received encrypted message
428 * @param msg the key exchange message
431 GCC_handle_kx_auth (struct CadetConnection *cc,
432 const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
434 if (CADET_CONNECTION_SENT == cc->state)
436 /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
437 clearly something is working, so pretend we got an ACK. */
438 LOG (GNUNET_ERROR_TYPE_DEBUG,
439 "Faking connection CADET_CONNECTION_CREATE_ACK for %s due to KX\n",
441 GCC_handle_connection_create_ack (cc);
443 GCT_handle_kx_auth (cc->ct,
449 * Handle encrypted message.
451 * @param cc connection that received encrypted message
452 * @param msg the encrypted message to decrypt
455 GCC_handle_encrypted (struct CadetConnection *cc,
456 const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
458 if (CADET_CONNECTION_SENT == cc->state)
460 /* We didn't get the CREATE_ACK, but instead got payload. That's fine,
461 clearly something is working, so pretend we got an ACK. */
462 LOG (GNUNET_ERROR_TYPE_DEBUG,
463 "Faking connection ACK for %s due to ENCRYPTED payload\n",
465 GCC_handle_connection_create_ack (cc);
467 GCT_handle_encrypted (cc->ct,
473 * Send a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE message to the
476 * @param cls the `struct CadetConnection` to initiate
479 send_create (void *cls)
481 struct CadetConnection *cc = cls;
482 struct GNUNET_CADET_ConnectionCreateMessage *create_msg;
483 struct GNUNET_PeerIdentity *pids;
484 struct GNUNET_MQ_Envelope *env;
485 unsigned int path_length;
488 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
489 path_length = GCPP_get_length (cc->path);
490 env = GNUNET_MQ_msg_extra (create_msg,
491 (1 + path_length) * sizeof (struct GNUNET_PeerIdentity),
492 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
493 create_msg->cid = cc->cid;
494 pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
495 pids[0] = my_full_id;
496 for (unsigned int i=0;i<path_length;i++)
497 pids[i + 1] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
499 LOG (GNUNET_ERROR_TYPE_DEBUG,
500 "Sending CADET_CONNECTION_CREATE message for %s\n",
504 CADET_CONNECTION_SENT,
506 GCP_send (cc->mq_man,
512 * Send a CREATE_ACK message towards the origin.
514 * @param cls the `struct CadetConnection` to initiate
517 send_create_ack (void *cls)
519 struct CadetConnection *cc = cls;
520 struct GNUNET_CADET_ConnectionCreateAckMessage *ack_msg;
521 struct GNUNET_MQ_Envelope *env;
524 GNUNET_assert (CADET_CONNECTION_CREATE_RECEIVED == cc->state);
525 LOG (GNUNET_ERROR_TYPE_DEBUG,
526 "Sending CONNECTION_CREATE_ACK message for %s\n",
528 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
529 env = GNUNET_MQ_msg (ack_msg,
530 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK);
531 ack_msg->cid = cc->cid;
534 CADET_CONNECTION_READY,
536 GCP_send (cc->mq_man,
542 * We got a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a
543 * connection that we already have. Either our ACK got lost
544 * or something is fishy. Consider retransmitting the ACK.
546 * @param cc connection that got the duplicate CREATE
549 GCC_handle_duplicate_create (struct CadetConnection *cc)
551 if (GNUNET_YES == cc->mqm_ready)
553 LOG (GNUNET_ERROR_TYPE_DEBUG,
554 "Got duplicate CREATE for %s, scheduling another ACK (%s)\n",
556 (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy");
557 /* Revert back to the state of having only received the 'CREATE',
558 and immediately proceed to send the CREATE_ACK. */
560 CADET_CONNECTION_CREATE_RECEIVED,
562 if (NULL != cc->task)
563 GNUNET_SCHEDULER_cancel (cc->task);
564 cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
569 /* We are currently sending something else back, which
570 can only be an ACK or payload, either of which would
571 do. So actually no need to do anything. */
572 LOG (GNUNET_ERROR_TYPE_DEBUG,
573 "Got duplicate CREATE for %s. MQ is busy, not queueing another ACK\n",
580 * There has been a change in the message queue existence for our
581 * peer at the first hop. Adjust accordingly.
583 * @param cls the `struct CadetConnection`
584 * @param available #GNUNET_YES if sending is now possible,
585 * #GNUNET_NO if sending is no longer possible
586 * #GNUNET_SYSERR if sending is no longer possible
587 * and the last envelope was discarded
590 manage_first_hop_mq (void *cls,
593 struct CadetConnection *cc = cls;
595 if (GNUNET_YES != available)
597 /* Connection is down, for now... */
598 LOG (GNUNET_ERROR_TYPE_DEBUG,
599 "Core MQ for %s went down\n",
602 CADET_CONNECTION_NEW,
604 cc->retry_delay = GNUNET_TIME_UNIT_ZERO;
605 if (NULL != cc->task)
607 GNUNET_SCHEDULER_cancel (cc->task);
616 LOG (GNUNET_ERROR_TYPE_DEBUG,
617 "Core MQ for %s became available in state %d\n",
622 case CADET_CONNECTION_NEW:
623 /* Transmit immediately */
624 cc->task = GNUNET_SCHEDULER_add_now (&send_create,
627 case CADET_CONNECTION_SENDING_CREATE:
628 /* Should not be possible to be called in this state. */
631 case CADET_CONNECTION_SENT:
632 /* Retry a bit later... */
633 cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
634 cc->task = GNUNET_SCHEDULER_add_delayed (cc->retry_delay,
638 case CADET_CONNECTION_CREATE_RECEIVED:
639 /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */
640 cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
643 case CADET_CONNECTION_READY:
644 if ( (NULL == cc->keepalive_qe) &&
645 (GNUNET_YES == cc->mqm_ready) &&
648 LOG (GNUNET_ERROR_TYPE_DEBUG,
649 "Scheduling keepalive for %s in %s\n",
651 GNUNET_STRINGS_relative_time_to_string (keepalive_period,
653 cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
663 * Create a connection to @a destination via @a path and notify @a cb
664 * whenever we are ready for more data. Shared logic independent of
665 * who is initiating the connection.
667 * @param destination where to go
668 * @param path which path to take (may not be the full path)
669 * @param ct which tunnel uses this connection
670 * @param init_state initial state for the connection
671 * @param ready_cb function to call when ready to transmit
672 * @param ready_cb_cls closure for @a cb
673 * @return handle to the connection
675 static struct CadetConnection *
676 connection_create (struct CadetPeer *destination,
677 struct CadetPeerPath *path,
678 struct CadetTConnection *ct,
679 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
680 enum CadetConnectionState init_state,
681 GCC_ReadyCallback ready_cb,
684 struct CadetConnection *cc;
685 struct CadetPeer *first_hop;
688 off = GCPP_find_peer (path,
690 GNUNET_assert (UINT_MAX > off);
691 cc = GNUNET_new (struct CadetConnection);
692 cc->state = init_state;
695 GNUNET_assert (GNUNET_OK ==
696 GNUNET_CONTAINER_multishortmap_put (connections,
697 &GCC_get_id (cc)->connection_of_tunnel,
699 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
700 cc->ready_cb = ready_cb;
701 cc->ready_cb_cls = ready_cb_cls;
704 LOG (GNUNET_ERROR_TYPE_DEBUG,
705 "Creating %s using path %s\n",
708 GCPP_add_connection (path,
711 for (unsigned int i=0;i<off;i++)
712 GCP_add_connection (GCPP_get_peer_at_offset (path,
716 first_hop = GCPP_get_peer_at_offset (path,
718 cc->mq_man = GCP_request_mq (first_hop,
719 &manage_first_hop_mq,
726 * Create a connection to @a destination via @a path and
727 * notify @a cb whenever we are ready for more data. This
728 * is an inbound tunnel, so we must use the existing @a cid
730 * @param destination where to go
731 * @param path which path to take (may not be the full path)
732 * @param ct which tunnel uses this connection
733 * @param ready_cb function to call when ready to transmit
734 * @param ready_cb_cls closure for @a cb
735 * @return handle to the connection, NULL if we already have
736 * a connection that takes precedence on @a path
738 struct CadetConnection *
739 GCC_create_inbound (struct CadetPeer *destination,
740 struct CadetPeerPath *path,
741 struct CadetTConnection *ct,
742 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
743 GCC_ReadyCallback ready_cb,
746 struct CadetConnection *cc;
749 off = GCPP_find_peer (path,
751 GNUNET_assert (UINT_MAX != off);
752 cc = GCPP_get_connection (path,
764 /* Two peers picked the SAME random connection identifier at the
765 same time for the same path? Must be malicious. Drop
766 connection (existing and inbound), even if it is the only
769 GCT_connection_lost (cc->ct);
770 GCC_destroy_without_tunnel (cc);
776 LOG (GNUNET_ERROR_TYPE_DEBUG,
777 "Got two connections on %s, dropping my existing %s\n",
780 GCT_connection_lost (cc->ct);
781 GCC_destroy_without_tunnel (cc);
786 LOG (GNUNET_ERROR_TYPE_DEBUG,
787 "Got two connections on %s, keeping my existing %s\n",
794 return connection_create (destination,
798 CADET_CONNECTION_CREATE_RECEIVED,
805 * Create a connection to @a destination via @a path and
806 * notify @a cb whenever we are ready for more data.
808 * @param destination where to go
809 * @param path which path to take (may not be the full path)
810 * @param ct tunnel that uses the connection
811 * @param ready_cb function to call when ready to transmit
812 * @param ready_cb_cls closure for @a cb
813 * @return handle to the connection
815 struct CadetConnection *
816 GCC_create (struct CadetPeer *destination,
817 struct CadetPeerPath *path,
818 struct CadetTConnection *ct,
819 GCC_ReadyCallback ready_cb,
822 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
824 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
827 return connection_create (destination,
831 CADET_CONNECTION_NEW,
838 * Transmit message @a msg via connection @a cc. Must only be called
839 * (once) after the connection has signalled that it is ready via the
840 * `ready_cb`. Clients can also use #GCC_is_ready() to check if the
841 * connection is right now ready for transmission.
843 * @param cc connection identification
844 * @param env envelope with message to transmit; must NOT
845 * yet have a #GNUNET_MQ_notify_sent() callback attached to it
848 GCC_transmit (struct CadetConnection *cc,
849 struct GNUNET_MQ_Envelope *env)
851 LOG (GNUNET_ERROR_TYPE_DEBUG,
852 "Scheduling message for transmission on %s\n",
854 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
855 GNUNET_assert (CADET_CONNECTION_READY == cc->state);
856 cc->mqm_ready = GNUNET_NO;
857 if (NULL != cc->task)
859 GNUNET_SCHEDULER_cancel (cc->task);
862 GCP_send (cc->mq_man,
868 * Obtain the path used by this connection.
870 * @param cc connection
871 * @return path to @a cc
873 struct CadetPeerPath *
874 GCC_get_path (struct CadetConnection *cc)
881 * Obtain unique ID for the connection.
883 * @param cc connection.
884 * @return unique number of the connection
886 const struct GNUNET_CADET_ConnectionTunnelIdentifier *
887 GCC_get_id (struct CadetConnection *cc)
894 * Get a (static) string for a connection.
896 * @param cc Connection.
899 GCC_2s (const struct CadetConnection *cc)
901 static char buf[128];
904 return "Connection(NULL)";
908 GNUNET_snprintf (buf,
910 "Connection %s (%s)",
911 GNUNET_sh2s (&cc->cid.connection_of_tunnel),
915 GNUNET_snprintf (buf,
918 GNUNET_sh2s (&cc->cid.connection_of_tunnel));
923 #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-con",__VA_ARGS__)
927 * Log connection info.
929 * @param cc connection
930 * @param level Debug level to use.
933 GCC_debug (struct CadetConnection *cc,
934 enum GNUNET_ErrorType level)
938 do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
940 __FILE__, __FUNCTION__, __LINE__);
946 "Connection (NULL)\n");
950 "%s to %s via path %s in state %d is %s\n",
952 GCP_2s (cc->destination),
955 (GNUNET_YES == cc->mqm_ready) ? "ready" : "busy");
958 /* end of gnunet-service-cadet-new_connection.c */