3 This file is part of GNUnet.
4 Copyright (C) 2001-2017 GNUnet e.V.
6 GNUnet is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 3, or (at your
9 option) any later version.
11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNUnet; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
23 * @file cadet/gnunet-service-cadet-new_connection.c
24 * @brief management of CORE-level end-to-end connections; establishes
25 * end-to-end routes and transmits messages along the route
26 * @author Bartlomiej Polot
27 * @author Christian Grothoff
30 * - congestion control
32 * - keepalive messages
33 * - performance metrics
37 #include "gnunet-service-cadet-new_channel.h"
38 #include "gnunet-service-cadet-new_connection.h"
39 #include "gnunet-service-cadet-new_paths.h"
40 #include "gnunet-service-cadet-new_peer.h"
41 #include "gnunet-service-cadet-new_tunnels.h"
42 #include "gnunet_cadet_service.h"
43 #include "cadet_protocol.h"
47 * All the states a connection can be in.
49 enum CadetConnectionState
52 * Uninitialized status, we have not yet even gotten the message queue.
57 * Connection create message in queue, awaiting transmission by CORE.
59 CADET_CONNECTION_SENDING_CREATE,
62 * Connection create message sent, waiting for ACK.
64 CADET_CONNECTION_SENT,
67 * Connection confirmed, ready to carry traffic.
69 CADET_CONNECTION_READY,
72 * Connection to be destroyed, just waiting to empty queues.
74 CADET_CONNECTION_DESTROYED,
77 * Connection to be destroyed because of a distant peer, same as DESTROYED.
79 CADET_CONNECTION_BROKEN
84 * Low-level connection to a destination.
86 struct CadetConnection
90 * ID of the connection.
92 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
95 * To which peer does this connection go?
97 struct CadetPeer *destination;
100 * Which tunnel is using this connection?
102 struct CadetTConnection *ct;
105 * Path we are using to our destination.
107 struct CadetPeerPath *path;
110 * Pending message, NULL if we are ready to transmit.
112 struct GNUNET_MQ_Envelope *env;
115 * Message queue to the first hop, or NULL if we have no connection yet.
117 struct GNUNET_MQ_Handle *mq;
120 * Handle for calling #GCP_request_mq_cancel() once we are finished.
122 struct GCP_MessageQueueManager *mq_man;
125 * Task for connection maintenance.
127 struct GNUNET_SCHEDULER_Task *task;
130 * Function to call once we are ready to transmit.
132 GNUNET_SCHEDULER_TaskCallback ready_cb;
135 * Closure for @e ready_cb.
140 * How long do we wait before we try again with a CREATE message?
142 struct GNUNET_TIME_Relative retry_delay;
145 * State of the connection.
147 enum CadetConnectionState state;
150 * Offset of our @e destination in @e path.
158 * Is the given connection currently ready for transmission?
160 * @param cc connection to transmit on
161 * @return #GNUNET_YES if we could transmit
164 GCC_is_ready (struct CadetConnection *cc)
166 return ( (NULL != cc->mq) &&
167 (CADET_CONNECTION_READY == cc->state) &&
168 (NULL == cc->env) ) ? GNUNET_YES : GNUNET_NO;
173 * Destroy a connection.
175 * @param cc connection to destroy
178 GCC_destroy (struct CadetConnection *cc)
183 GNUNET_MQ_send_cancel (cc->env);
185 GNUNET_MQ_discard (cc->env);
188 if ( (NULL != cc->mq) &&
189 (CADET_CONNECTION_SENDING_CREATE != cc->state) )
191 /* Need to notify next hop that we are down. */
192 struct GNUNET_MQ_Envelope *env;
193 struct GNUNET_CADET_ConnectionDestroy *destroy_msg;
195 env = GNUNET_MQ_msg (destroy_msg,
196 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY);
197 destroy_msg->cid = cc->cid;
198 GNUNET_MQ_send (cc->mq,
202 GCP_request_mq_cancel (cc->mq_man);
204 GCPP_del_connection (cc->path,
207 GNUNET_assert (GNUNET_YES ==
208 GNUNET_CONTAINER_multishortmap_remove (connections,
209 &GCC_get_id (cc)->connection_of_tunnel,
216 * Return the tunnel associated with this connection.
218 * @param cc connection to query
219 * @return corresponding entry in the tunnel's connection list
221 struct CadetTConnection *
222 GCC_get_ct (struct CadetConnection *cc)
229 * A connection ACK was received for this connection, implying
230 * that the end-to-end connection is up. Process it.
232 * @param cc the connection that got the ACK.
235 GCC_handle_connection_ack (struct CadetConnection *cc)
237 GNUNET_SCHEDULER_cancel (cc->task);
239 cc->task = GNUNET_SCHEDULER_add_delayed (cc->keepalive_period,
243 cc->state = CADET_CONNECTION_READY;
244 cc->ready_cb (cc->ready_cb_cls);
251 * @param cc connection that received encrypted message
252 * @param msg the key exchange message
255 GCC_handle_kx (struct CadetConnection *cc,
256 const struct GNUNET_CADET_KX *msg)
258 GCT_handle_kx (cc->ct,
264 * Handle encrypted message.
266 * @param cc connection that received encrypted message
267 * @param msg the encrypted message to decrypt
270 GCC_handle_encrypted (struct CadetConnection *cc,
271 const struct GNUNET_CADET_Encrypted *msg)
273 GCT_handle_encrypted (cc->ct,
279 * Send a CREATE message to the first hop.
281 * @param cls the `struct CadetConnection` to initiate
284 send_create (void *cls);
288 * We finished transmission of the create message, now wait for
291 * @param cls the `struct CadetConnection` that sent the create message
294 transmit_create_done_cb (void *cls)
296 struct CadetConnection *cc = cls;
298 cc->state = CADET_CONNECTION_SENT;
300 /* FIXME: at some point, we need to reset the delay back to 0! */
301 cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
302 cc->task = GNUNET_SCHEDULER_add_delayed (cc->retry_delay,
309 * Send a CREATE message to the first hop.
311 * @param cls the `struct CadetConnection` to initiate
314 send_create (void *cls)
316 struct CadetConnection *cc = cls;
317 struct GNUNET_CADET_ConnectionCreate *create_msg;
318 struct GNUNET_PeerIdentity *pids;
319 struct GNUNET_MQ_Envelope *env;
320 unsigned int path_length;
323 GNUNET_assert (NULL != cc->mq);
324 path_length = GCPP_get_length (cc->path);
325 env = GNUNET_MQ_msg_extra (create_msg,
326 path_length * sizeof (struct GNUNET_PeerIdentity),
327 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
328 create_msg->cid = cc->cid;
329 pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
330 for (unsigned int i=0;i<path_length;i++)
331 pids[i] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
334 GNUNET_MQ_notify_sent (env,
335 &transmit_create_done_cb,
337 GNUNET_MQ_send (cc->mq,
343 * There has been a change in the message queue existence for our
344 * peer at the first hop. Adjust accordingly.
346 * @param cls the `struct CadetConnection`
347 * @param mq NULL if the CORE connection was lost, non-NULL if
348 * it became available
351 manage_first_hop_mq (void *cls,
352 struct GNUNET_MQ_Handle *mq)
354 struct CadetConnection *cc = cls;
358 /* Connection is down, for now... */
360 if (NULL != cc->task)
362 GNUNET_SCHEDULER_cancel (cc->task);
369 cc->state = CADET_CONNECTION_SENDING_CREATE;
371 /* Now repeat sending connection creation messages
372 down the path, until we get an ACK! */
373 cc->task = GNUNET_SCHEDULER_add_now (&send_create,
379 * Create a connection to @a destination via @a path and
380 * notify @a cb whenever we are ready for more data.
382 * @param destination where to go
383 * @param path which path to take (may not be the full path)
384 * @param ct tunnel that uses the connection
385 * @param ready_cb function to call when ready to transmit
386 * @param ready_cb_cls closure for @a cb
387 * @return handle to the connection
389 struct CadetConnection *
390 GCC_create (struct CadetPeer *destination,
391 struct CadetPeerPath *path,
392 struct CadetTConnection *ct,
393 GNUNET_SCHEDULER_TaskCallback ready_cb,
396 struct CadetConnection *cc;
397 struct CadetPeer *first_hop;
400 off = GCPP_find_peer (path,
402 GNUNET_assert (UINT_MAX > off);
403 cc = GNUNET_new (struct CadetConnection);
405 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
408 GNUNET_assert (GNUNET_OK ==
409 GNUNET_CONTAINER_multishortmap_put (connections,
410 &GCC_get_id (cc)->connection_of_tunnel,
412 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
413 cc->ready_cb = ready_cb;
414 cc->ready_cb_cls = ready_cb_cls;
417 GCPP_add_connection (path,
420 for (unsigned int i=0;i<off;i++)
421 GCP_add_connection (GCPP_get_peer_at_offset (path,
425 first_hop = GCPP_get_peer_at_offset (path,
427 cc->mq_man = GCP_request_mq (first_hop,
428 &manage_first_hop_mq,
435 * We finished transmission of a message, if we are still ready, tell
438 * @param cls our `struct CadetConnection`
441 transmit_done_cb (void *cls)
443 struct CadetConnection *cc = cls;
446 if ( (NULL != cc->mq) &&
447 (CADET_CONNECTION_READY == cc->state) )
448 cc->ready_cb (cc->ready_cb_cls);
453 * Transmit message @a msg via connection @a cc. Must only be called
454 * (once) after the connection has signalled that it is ready via the
455 * `ready_cb`. Clients can also use #GCC_is_ready() to check if the
456 * connection is right now ready for transmission.
458 * @param cc connection identification
459 * @param env envelope with message to transmit
462 GCC_transmit (struct CadetConnection *cc,
463 struct GNUNET_MQ_Envelope *env)
465 GNUNET_assert (NULL == cc->env);
467 GNUNET_MQ_notify_sent (env,
470 if ( (NULL != cc->mq) &&
471 (CADET_CONNECTION_READY == cc->state) )
472 GNUNET_MQ_send (cc->mq,
478 * Obtain the path used by this connection.
480 * @param cc connection
481 * @return path to @a cc
483 struct CadetPeerPath *
484 GCC_get_path (struct CadetConnection *cc)
491 * Obtain unique ID for the connection.
493 * @param cc connection.
494 * @return unique number of the connection
496 const struct GNUNET_CADET_ConnectionTunnelIdentifier *
497 GCC_get_id (struct CadetConnection *cc)
504 * Log connection info.
506 * @param cc connection
507 * @param level Debug level to use.
510 GCC_debug (struct CadetConnection *cc,
511 enum GNUNET_ErrorType level)
513 GNUNET_break (0); // FIXME: implement...
516 /* end of gnunet-service-cadet-new_connection.c */