Merge branch 'master' of gnunet.org:gnunet
[oweals/gnunet.git] / src / cadet / gnunet-service-cadet_connection.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2001-2017 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
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      Affero General Public License for more details.
14     
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21 /**
22  * @file cadet/gnunet-service-cadet_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
27  */
28 #include "platform.h"
29 #include "gnunet-service-cadet_connection.h"
30 #include "gnunet-service-cadet_channel.h"
31 #include "gnunet-service-cadet_paths.h"
32 #include "gnunet-service-cadet_tunnels.h"
33 #include "gnunet_cadet_service.h"
34 #include "gnunet_statistics_service.h"
35 #include "cadet_protocol.h"
36
37
38 #define LOG(level, ...) GNUNET_log_from(level,"cadet-con",__VA_ARGS__)
39
40
41 /**
42  * How long do we wait initially before retransmitting the KX?
43  * TODO: replace by 2 RTT if/once we have connection-level RTT data!
44  */
45 #define INITIAL_CONNECTION_CREATE_RETRY_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 200)
46
47
48 /**
49  * All the states a connection can be in.
50  */
51 enum CadetConnectionState
52 {
53   /**
54    * Uninitialized status, we have not yet even gotten the message queue.
55    */
56   CADET_CONNECTION_NEW,
57
58   /**
59    * Connection create message in queue, awaiting transmission by CORE.
60    */
61   CADET_CONNECTION_SENDING_CREATE,
62
63   /**
64    * Connection create message sent, waiting for ACK.
65    */
66   CADET_CONNECTION_SENT,
67
68   /**
69    * We are an inbound connection, and received a CREATE. Need to
70    * send an CREATE_ACK back.
71    */
72   CADET_CONNECTION_CREATE_RECEIVED,
73
74   /**
75    * Connection confirmed, ready to carry traffic.
76    */
77   CADET_CONNECTION_READY
78
79 };
80
81
82 /**
83  * Low-level connection to a destination.
84  */
85 struct CadetConnection
86 {
87
88   /**
89    * ID of the connection.
90    */
91   struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
92
93   /**
94    * To which peer does this connection go?
95    */
96   struct CadetPeer *destination;
97
98   /**
99    * Which tunnel is using this connection?
100    */
101   struct CadetTConnection *ct;
102
103   /**
104    * Path we are using to our destination.
105    */
106   struct CadetPeerPath *path;
107
108   /**
109    * Pending message, NULL if we are ready to transmit.
110    */
111   struct GNUNET_MQ_Envelope *env;
112
113   /**
114    * Handle for calling #GCP_request_mq_cancel() once we are finished.
115    */
116   struct GCP_MessageQueueManager *mq_man;
117
118   /**
119    * Task for connection maintenance.
120    */
121   struct GNUNET_SCHEDULER_Task *task;
122
123   /**
124    * Queue entry for keepalive messages.
125    */
126   struct CadetTunnelQueueEntry *keepalive_qe;
127
128   /**
129    * Function to call once we are ready to transmit.
130    */
131   GCC_ReadyCallback ready_cb;
132
133   /**
134    * Closure for @e ready_cb.
135    */
136   void *ready_cb_cls;
137
138   /**
139    * How long do we wait before we try again with a CREATE message?
140    */
141   struct GNUNET_TIME_Relative retry_delay;
142
143   /**
144    * Earliest time for re-trying CREATE
145    */
146   struct GNUNET_TIME_Absolute create_at;
147
148   /**
149    * Earliest time for re-trying CREATE_ACK
150    */
151   struct GNUNET_TIME_Absolute create_ack_at;
152
153   /**
154    * Performance metrics for this connection.
155    */
156   struct CadetConnectionMetrics metrics;
157
158   /**
159    * State of the connection.
160    */
161   enum CadetConnectionState state;
162
163   /**
164    * Options for the route, control buffering.
165    */
166   enum GNUNET_CADET_ChannelOption options;
167
168   /**
169    * How many latency observations did we make for this connection?
170    */
171   unsigned int latency_datapoints;
172
173   /**
174    * Offset of our @e destination in @e path.
175    */
176   unsigned int off;
177
178   /**
179    * Are we ready to transmit via @e mq_man right now?
180    */
181   int mqm_ready;
182
183 };
184
185
186 /**
187  * Lookup a connection by its identifier.
188  *
189  * @param cid identifier to resolve
190  * @return NULL if connection was not found
191  */
192 struct CadetConnection *
193 GCC_lookup (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
194 {
195   return GNUNET_CONTAINER_multishortmap_get (connections,
196                                              &cid->connection_of_tunnel);
197 }
198
199
200 /**
201  * Update the connection state. Also triggers the necessary
202  * MQM notifications.
203  *
204  * @param cc connection to update the state for
205  * @param new_state new state for @a cc
206  * @param new_mqm_ready new `mqm_ready` state for @a cc
207  */
208 static void
209 update_state (struct CadetConnection *cc,
210               enum CadetConnectionState new_state,
211               int new_mqm_ready)
212 {
213   int old_ready;
214   int new_ready;
215
216   if ( (new_state == cc->state) &&
217        (new_mqm_ready == cc->mqm_ready) )
218     return; /* no change, nothing to do */
219   old_ready = ( (CADET_CONNECTION_READY == cc->state) &&
220                 (GNUNET_YES == cc->mqm_ready) );
221   new_ready = ( (CADET_CONNECTION_READY == new_state) &&
222                 (GNUNET_YES == new_mqm_ready) );
223   cc->state = new_state;
224   cc->mqm_ready = new_mqm_ready;
225   if (old_ready != new_ready)
226     cc->ready_cb (cc->ready_cb_cls,
227                   new_ready);
228 }
229
230
231 /**
232  * Destroy a connection, part of the internal implementation.  Called
233  * only from #GCC_destroy_from_core() or #GCC_destroy_from_tunnel().
234  *
235  * @param cc connection to destroy
236  */
237 static void
238 GCC_destroy (struct CadetConnection *cc)
239 {
240   LOG (GNUNET_ERROR_TYPE_DEBUG,
241        "Destroying %s\n",
242        GCC_2s (cc));
243   if (NULL != cc->mq_man)
244   {
245     GCP_request_mq_cancel (cc->mq_man,
246                            NULL);
247     cc->mq_man = NULL;
248   }
249   if (NULL != cc->task)
250   {
251     GNUNET_SCHEDULER_cancel (cc->task);
252     cc->task = NULL;
253   }
254   if (NULL != cc->keepalive_qe)
255   {
256     GCT_send_cancel (cc->keepalive_qe);
257     cc->keepalive_qe = NULL;
258   }
259   GCPP_del_connection (cc->path,
260                        cc->off,
261                        cc);
262   for (unsigned int i=0;i<cc->off;i++)
263     GCP_remove_connection (GCPP_get_peer_at_offset (cc->path,
264                                                     i),
265                            cc);
266   GNUNET_assert (GNUNET_YES ==
267                  GNUNET_CONTAINER_multishortmap_remove (connections,
268                                                         &GCC_get_id (cc)->connection_of_tunnel,
269                                                         cc));
270   GNUNET_free (cc);
271 }
272
273
274
275 /**
276  * Destroy a connection, called when the CORE layer is already done
277  * (i.e. has received a BROKEN message), but if we still have to
278  * communicate the destruction of the connection to the tunnel (if one
279  * exists).
280  *
281  * @param cc connection to destroy
282  */
283 void
284 GCC_destroy_without_core (struct CadetConnection *cc)
285 {
286   if (NULL != cc->ct)
287   {
288     GCT_connection_lost (cc->ct);
289     cc->ct = NULL;
290   }
291   GCC_destroy (cc);
292 }
293
294
295 /**
296  * Destroy a connection, called if the tunnel association with the
297  * connection was already broken, but we still need to notify the CORE
298  * layer about the breakage.
299  *
300  * @param cc connection to destroy
301  */
302 void
303 GCC_destroy_without_tunnel (struct CadetConnection *cc)
304 {
305   cc->ct = NULL;
306   if ( (CADET_CONNECTION_SENDING_CREATE != cc->state) &&
307        (NULL != cc->mq_man) )
308   {
309     struct GNUNET_MQ_Envelope *env;
310     struct GNUNET_CADET_ConnectionDestroyMessage *destroy_msg;
311
312     /* Need to notify next hop that we are down. */
313     env = GNUNET_MQ_msg (destroy_msg,
314                          GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY);
315     destroy_msg->cid = cc->cid;
316     GCP_request_mq_cancel (cc->mq_man,
317                            env);
318     cc->mq_man = NULL;
319   }
320   GCC_destroy (cc);
321 }
322
323
324 /**
325  * Return the tunnel associated with this connection.
326  *
327  * @param cc connection to query
328  * @return corresponding entry in the tunnel's connection list
329  */
330 struct CadetTConnection *
331 GCC_get_ct (struct CadetConnection *cc)
332 {
333   return cc->ct;
334 }
335
336
337 /**
338  * Obtain performance @a metrics from @a cc.
339  *
340  * @param cc connection to query
341  * @return the metrics
342  */
343 const struct CadetConnectionMetrics *
344 GCC_get_metrics (struct CadetConnection *cc)
345 {
346   return &cc->metrics;
347 }
348
349
350 /**
351  * Send a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE through the
352  * tunnel to prevent it from timing out.
353  *
354  * @param cls the `struct CadetConnection` to keep alive.
355  */
356 static void
357 send_keepalive (void *cls);
358
359
360 /**
361  * Keepalive was transmitted.  Remember this, and possibly
362  * schedule the next one.
363  *
364  * @param cls the `struct CadetConnection` to keep alive.
365  * @param cid identifier of the connection within the tunnel, NULL
366  *            if transmission failed
367  */
368 static void
369 keepalive_done (void *cls,
370                 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
371 {
372   struct CadetConnection *cc = cls;
373
374   cc->keepalive_qe = NULL;
375   if ( (GNUNET_YES == cc->mqm_ready) &&
376        (NULL == cc->task) )
377     cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
378                                              &send_keepalive,
379                                              cc);
380 }
381
382
383 /**
384  * Send a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE through the
385  * tunnel to prevent it from timing out.
386  *
387  * @param cls the `struct CadetConnection` to keep alive.
388  */
389 static void
390 send_keepalive (void *cls)
391 {
392   struct CadetConnection *cc = cls;
393   struct GNUNET_MessageHeader msg;
394
395   cc->task = NULL;
396   if (CADET_TUNNEL_KEY_OK != GCT_get_estate (cc->ct->t))
397   {
398     /* Tunnel not yet ready, wait with keepalives... */
399     cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
400                                              &send_keepalive,
401                                              cc);
402     return;
403   }
404   GNUNET_assert (NULL != cc->ct);
405   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
406   GNUNET_assert (NULL == cc->keepalive_qe);
407   LOG (GNUNET_ERROR_TYPE_INFO,
408        "Sending KEEPALIVE on behalf of %s via %s\n",
409        GCC_2s (cc),
410        GCT_2s (cc->ct->t));
411   GNUNET_STATISTICS_update (stats,
412                             "# keepalives sent",
413                             1,
414                             GNUNET_NO);
415   msg.size = htons (sizeof (msg));
416   msg.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE);
417
418   cc->keepalive_qe
419     = GCT_send (cc->ct->t,
420                 &msg,
421                 &keepalive_done,
422                 cc);
423 }
424
425
426 /**
427  * We sent a message for which we expect to receive an ACK via
428  * the connection identified by @a cti.
429  *
430  * @param cid connection identifier where we expect an ACK
431  */
432 void
433 GCC_ack_expected (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
434 {
435   struct CadetConnection *cc;
436
437   cc = GCC_lookup (cid);
438   if (NULL == cc)
439     return; /* whopise, connection alredy down? */
440   cc->metrics.num_acked_transmissions++;
441 }
442
443
444 /**
445  * We observed an ACK for a message that was originally sent via
446  * the connection identified by @a cti.
447  *
448  * @param cti connection identifier where we got an ACK for a message
449  *            that was originally sent via this connection (the ACK
450  *            may have gotten back to us via a different connection).
451  */
452 void
453 GCC_ack_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
454 {
455   struct CadetConnection *cc;
456
457   cc = GCC_lookup (cid);
458   if (NULL == cc)
459     return; /* whopise, connection alredy down? */
460   cc->metrics.num_successes++;
461 }
462
463
464 /**
465  * We observed some the given @a latency on the connection
466  * identified by @a cti.  (The same connection was taken
467  * in both directions.)
468  *
469  * @param cid connection identifier where we measured latency
470  * @param latency the observed latency
471  */
472 void
473 GCC_latency_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
474                       struct GNUNET_TIME_Relative latency)
475 {
476   struct CadetConnection *cc;
477   double weight;
478   double result;
479
480   cc = GCC_lookup (cid);
481   if (NULL == cc)
482     return; /* whopise, connection alredy down? */
483   GNUNET_STATISTICS_update (stats,
484                             "# latencies observed",
485                             1,
486                             GNUNET_NO);
487   cc->latency_datapoints++;
488   if (cc->latency_datapoints >= 7)
489     weight = 7.0;
490   else
491     weight = cc->latency_datapoints;
492   /* Compute weighted average, giving at MOST weight 7 to the
493      existing values, or less if that value is based on fewer than 7
494      measurements. */
495   result = (weight * cc->metrics.aged_latency.rel_value_us) + 1.0 * latency.rel_value_us;
496   result /= (weight + 1.0);
497   cc->metrics.aged_latency.rel_value_us = (uint64_t) result;
498 }
499
500
501 /**
502  * A #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK was received for
503  * this connection, implying that the end-to-end connection is up.
504  * Process it.
505  *
506  * @param cc the connection that got the ACK.
507  */
508 void
509 GCC_handle_connection_create_ack (struct CadetConnection *cc)
510 {
511   LOG (GNUNET_ERROR_TYPE_DEBUG,
512        "Received CADET_CONNECTION_CREATE_ACK for %s in state %d (%s)\n",
513        GCC_2s (cc),
514        cc->state,
515        (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy");
516   if (CADET_CONNECTION_READY == cc->state)
517     return; /* Duplicate ACK, ignore */
518   if (NULL != cc->task)
519   {
520     GNUNET_SCHEDULER_cancel (cc->task);
521     cc->task = NULL;
522   }
523   cc->metrics.age = GNUNET_TIME_absolute_get ();
524   update_state (cc,
525                 CADET_CONNECTION_READY,
526                 cc->mqm_ready);
527   if ( (NULL == cc->keepalive_qe) &&
528        (GNUNET_YES == cc->mqm_ready) &&
529        (NULL == cc->task) )
530     cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
531                                              &send_keepalive,
532                                              cc);
533 }
534
535
536 /**
537  * Handle KX message.
538  *
539  * @param cc connection that received encrypted message
540  * @param msg the key exchange message
541  */
542 void
543 GCC_handle_kx (struct CadetConnection *cc,
544                const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
545 {
546   LOG (GNUNET_ERROR_TYPE_DEBUG,
547        "Received KX message with ephermal %s on CC %s in state %d\n",
548        GNUNET_e2s (&msg->ephemeral_key),
549        GNUNET_sh2s (&cc->cid.connection_of_tunnel),
550        cc->state);
551   if (CADET_CONNECTION_SENT == cc->state)
552   {
553     /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
554        clearly something is working, so pretend we got an ACK. */
555     LOG (GNUNET_ERROR_TYPE_DEBUG,
556          "Faking connection CADET_CONNECTION_CREATE_ACK for %s due to KX\n",
557          GCC_2s (cc));
558     GCC_handle_connection_create_ack (cc);
559   }
560   GCT_handle_kx (cc->ct,
561                  msg);
562 }
563
564
565 /**
566  * Handle KX_AUTH message.
567  *
568  * @param cc connection that received encrypted message
569  * @param msg the key exchange message
570  */
571 void
572 GCC_handle_kx_auth (struct CadetConnection *cc,
573                     const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
574 {
575   LOG (GNUNET_ERROR_TYPE_DEBUG,
576        "Received KX AUTH message with ephermal %s on CC %s in state %d\n",
577        GNUNET_e2s (&msg->kx.ephemeral_key),
578        GNUNET_sh2s (&cc->cid.connection_of_tunnel),
579        cc->state);
580   if (CADET_CONNECTION_SENT == cc->state)
581   {
582     /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
583        clearly something is working, so pretend we got an ACK. */
584     LOG (GNUNET_ERROR_TYPE_DEBUG,
585          "Faking connection CADET_CONNECTION_CREATE_ACK for %s due to KX\n",
586          GCC_2s (cc));
587     GCC_handle_connection_create_ack (cc);
588   }
589   GCT_handle_kx_auth (cc->ct,
590                       msg);
591 }
592
593
594 /**
595  * Handle encrypted message.
596  *
597  * @param cc connection that received encrypted message
598  * @param msg the encrypted message to decrypt
599  */
600 void
601 GCC_handle_encrypted (struct CadetConnection *cc,
602                       const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
603 {
604   if (CADET_CONNECTION_SENT == cc->state)
605   {
606     /* We didn't get the CREATE_ACK, but instead got payload. That's fine,
607        clearly something is working, so pretend we got an ACK. */
608     LOG (GNUNET_ERROR_TYPE_DEBUG,
609          "Faking connection ACK for %s due to ENCRYPTED payload\n",
610          GCC_2s (cc));
611     GCC_handle_connection_create_ack (cc);
612   }
613   cc->metrics.last_use = GNUNET_TIME_absolute_get ();
614   GCT_handle_encrypted (cc->ct,
615                         msg);
616 }
617
618
619 /**
620  * Send a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE message to the
621  * first hop.
622  *
623  * @param cls the `struct CadetConnection` to initiate
624  */
625 static void
626 send_create (void *cls)
627 {
628   struct CadetConnection *cc = cls;
629   struct GNUNET_CADET_ConnectionCreateMessage *create_msg;
630   struct GNUNET_PeerIdentity *pids;
631   struct GNUNET_MQ_Envelope *env;
632
633   cc->task = NULL;
634   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
635   env = GNUNET_MQ_msg_extra (create_msg,
636                              (2 + cc->off) * sizeof (struct GNUNET_PeerIdentity),
637                              GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
638   create_msg->options = htonl ((uint32_t) cc->options);
639   create_msg->cid = cc->cid;
640   pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
641   pids[0] = my_full_id;
642   for (unsigned int i=0;i<=cc->off;i++)
643     pids[i + 1] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
644                                                         i));
645   LOG (GNUNET_ERROR_TYPE_DEBUG,
646        "Sending CADET_CONNECTION_CREATE message for %s with %u hops\n",
647        GCC_2s (cc),
648        cc->off + 2);
649   cc->env = env;
650   cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
651   cc->create_at = GNUNET_TIME_relative_to_absolute (cc->retry_delay);
652   update_state (cc,
653                 CADET_CONNECTION_SENT,
654                 GNUNET_NO);
655   GCP_send (cc->mq_man,
656             env);
657 }
658
659
660 /**
661  * Send a CREATE_ACK message towards the origin.
662  *
663  * @param cls the `struct CadetConnection` to initiate
664  */
665 static void
666 send_create_ack (void *cls)
667 {
668   struct CadetConnection *cc = cls;
669   struct GNUNET_CADET_ConnectionCreateAckMessage *ack_msg;
670   struct GNUNET_MQ_Envelope *env;
671
672   cc->task = NULL;
673   LOG (GNUNET_ERROR_TYPE_DEBUG,
674        "Sending CONNECTION_CREATE_ACK message for %s\n",
675        GCC_2s (cc));
676   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
677   env = GNUNET_MQ_msg (ack_msg,
678                        GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK);
679   ack_msg->cid = cc->cid;
680   cc->env = env;
681   cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
682   cc->create_ack_at = GNUNET_TIME_relative_to_absolute (cc->retry_delay);
683   if (CADET_CONNECTION_CREATE_RECEIVED == cc->state)
684     update_state (cc,
685                   CADET_CONNECTION_READY,
686                   GNUNET_NO);
687   if (CADET_CONNECTION_READY == cc->state)
688     cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
689                                              &send_keepalive,
690                                              cc);
691   GCP_send (cc->mq_man,
692             env);
693 }
694
695
696 /**
697  * We got a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a
698  * connection that we already have.  Either our ACK got lost
699  * or something is fishy.  Consider retransmitting the ACK.
700  *
701  * @param cc connection that got the duplicate CREATE
702  */
703 void
704 GCC_handle_duplicate_create (struct CadetConnection *cc)
705 {
706   if (GNUNET_YES == cc->mqm_ready)
707   {
708     LOG (GNUNET_ERROR_TYPE_DEBUG,
709          "Got duplicate CREATE for %s, scheduling another ACK (%s)\n",
710          GCC_2s (cc),
711          (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy");
712     /* Revert back to the state of having only received the 'CREATE',
713        and immediately proceed to send the CREATE_ACK. */
714     update_state (cc,
715                   CADET_CONNECTION_CREATE_RECEIVED,
716                   cc->mqm_ready);
717     if (NULL != cc->task)
718       GNUNET_SCHEDULER_cancel (cc->task);
719     cc->task = GNUNET_SCHEDULER_add_at (cc->create_ack_at,
720                                         &send_create_ack,
721                                         cc);
722   }
723   else
724   {
725     /* We are currently sending something else back, which
726        can only be an ACK or payload, either of which would
727        do. So actually no need to do anything. */
728     LOG (GNUNET_ERROR_TYPE_DEBUG,
729          "Got duplicate CREATE for %s. MQ is busy, not queueing another ACK\n",
730          GCC_2s (cc));
731   }
732 }
733
734
735 /**
736  * There has been a change in the message queue existence for our
737  * peer at the first hop.  Adjust accordingly.
738  *
739  * @param cls the `struct CadetConnection`
740  * @param available #GNUNET_YES if sending is now possible,
741  *                  #GNUNET_NO if sending is no longer possible
742  *                  #GNUNET_SYSERR if sending is no longer possible
743  *                                 and the last envelope was discarded
744  */
745 static void
746 manage_first_hop_mq (void *cls,
747                      int available)
748 {
749   struct CadetConnection *cc = cls;
750
751   if (GNUNET_YES != available)
752   {
753     /* Connection is down, for now... */
754     LOG (GNUNET_ERROR_TYPE_DEBUG,
755          "Core MQ for %s went down\n",
756          GCC_2s (cc));
757     update_state (cc,
758                   CADET_CONNECTION_NEW,
759                   GNUNET_NO);
760     cc->retry_delay = INITIAL_CONNECTION_CREATE_RETRY_DELAY;
761     if (NULL != cc->task)
762     {
763       GNUNET_SCHEDULER_cancel (cc->task);
764       cc->task = NULL;
765     }
766     return;
767   }
768
769   update_state (cc,
770                 cc->state,
771                 GNUNET_YES);
772   LOG (GNUNET_ERROR_TYPE_DEBUG,
773        "Core MQ for %s became available in state %d\n",
774        GCC_2s (cc),
775        cc->state);
776   switch (cc->state)
777   {
778   case CADET_CONNECTION_NEW:
779     /* Transmit immediately */
780     cc->task = GNUNET_SCHEDULER_add_at (cc->create_at,
781                                         &send_create,
782                                         cc);
783     break;
784   case CADET_CONNECTION_SENDING_CREATE:
785     /* Should not be possible to be called in this state. */
786     GNUNET_assert (0);
787     break;
788   case CADET_CONNECTION_SENT:
789     /* Retry a bit later... */
790     cc->task = GNUNET_SCHEDULER_add_at (cc->create_at,
791                                         &send_create,
792                                         cc);
793     break;
794   case CADET_CONNECTION_CREATE_RECEIVED:
795     /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */
796     cc->metrics.age = GNUNET_TIME_absolute_get ();
797     cc->task = GNUNET_SCHEDULER_add_at (cc->create_ack_at,
798                                         &send_create_ack,
799                                         cc);
800     break;
801   case CADET_CONNECTION_READY:
802     if ( (NULL == cc->keepalive_qe) &&
803          (GNUNET_YES == cc->mqm_ready) &&
804          (NULL == cc->task) )
805     {
806       LOG (GNUNET_ERROR_TYPE_DEBUG,
807            "Scheduling keepalive for %s in %s\n",
808            GCC_2s (cc),
809            GNUNET_STRINGS_relative_time_to_string (keepalive_period,
810                                                    GNUNET_YES));
811       cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
812                                                &send_keepalive,
813                                                cc);
814     }
815     break;
816   }
817 }
818
819
820 /**
821  * Create a connection to @a destination via @a path and notify @a cb
822  * whenever we are ready for more data.  Shared logic independent of
823  * who is initiating the connection.
824  *
825  * @param destination where to go
826  * @param path which path to take (may not be the full path)
827  * @param off offset of @a destination on @a path
828  * @param options options for the connection
829  * @param ct which tunnel uses this connection
830  * @param init_state initial state for the connection
831  * @param ready_cb function to call when ready to transmit
832  * @param ready_cb_cls closure for @a cb
833  * @return handle to the connection
834  */
835 static struct CadetConnection *
836 connection_create (struct CadetPeer *destination,
837                    struct CadetPeerPath *path,
838                    unsigned int off,
839                    enum GNUNET_CADET_ChannelOption options,
840                    struct CadetTConnection *ct,
841                    const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
842                    enum CadetConnectionState init_state,
843                    GCC_ReadyCallback ready_cb,
844                    void *ready_cb_cls)
845 {
846   struct CadetConnection *cc;
847   struct CadetPeer *first_hop;
848
849   cc = GNUNET_new (struct CadetConnection);
850   cc->options = options;
851   cc->state = init_state;
852   cc->ct = ct;
853   cc->cid = *cid;
854   cc->retry_delay = GNUNET_TIME_relative_multiply (INITIAL_CONNECTION_CREATE_RETRY_DELAY,
855                                                    off);
856   GNUNET_assert (GNUNET_OK ==
857                  GNUNET_CONTAINER_multishortmap_put (connections,
858                                                      &GCC_get_id (cc)->connection_of_tunnel,
859                                                      cc,
860                                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
861   cc->ready_cb = ready_cb;
862   cc->ready_cb_cls = ready_cb_cls;
863   cc->path = path;
864   cc->off = off;
865   LOG (GNUNET_ERROR_TYPE_DEBUG,
866        "Creating %s using path %s (offset: %u)\n",
867        GCC_2s (cc),
868        GCPP_2s (path),
869        off);
870   GCPP_add_connection (path,
871                        off,
872                        cc);
873   for (unsigned int i=0;i<off;i++)
874     GCP_add_connection (GCPP_get_peer_at_offset (path,
875                                                  i),
876                         cc);
877   first_hop = GCPP_get_peer_at_offset (path,
878                                        0);
879   cc->mq_man = GCP_request_mq (first_hop,
880                                &manage_first_hop_mq,
881                                cc);
882   return cc;
883 }
884
885
886 /**
887  * Create a connection to @a destination via @a path and
888  * notify @a cb whenever we are ready for more data.  This
889  * is an inbound tunnel, so we must use the existing @a cid
890  *
891  * @param destination where to go
892  * @param path which path to take (may not be the full path)
893  * @param options options for the connection
894  * @param ct which tunnel uses this connection
895  * @param ready_cb function to call when ready to transmit
896  * @param ready_cb_cls closure for @a cb
897  * @return handle to the connection, NULL if we already have
898  *         a connection that takes precedence on @a path
899  */
900 struct CadetConnection *
901 GCC_create_inbound (struct CadetPeer *destination,
902                     struct CadetPeerPath *path,
903                     enum GNUNET_CADET_ChannelOption options,
904                     struct CadetTConnection *ct,
905                     const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
906                     GCC_ReadyCallback ready_cb,
907                     void *ready_cb_cls)
908 {
909   struct CadetConnection *cc;
910   unsigned int off;
911
912   off = GCPP_find_peer (path,
913                         destination);
914   GNUNET_assert (UINT_MAX != off);
915   cc = GCPP_get_connection (path,
916                             destination,
917                             off);
918   if (NULL != cc)
919   {
920     int cmp;
921
922     cmp = memcmp (cid,
923                   &cc->cid,
924                   sizeof (*cid));
925     if (0 == cmp)
926     {
927       /* Two peers picked the SAME random connection identifier at the
928          same time for the same path? Must be malicious.  Drop
929          connection (existing and inbound), even if it is the only
930          one. */
931       GNUNET_break_op (0);
932       GCT_connection_lost (cc->ct);
933       GCC_destroy_without_tunnel (cc);
934       return NULL;
935     }
936     if (0 < cmp)
937     {
938       /* drop existing */
939       LOG (GNUNET_ERROR_TYPE_DEBUG,
940            "Got two connections on %s, dropping my existing %s\n",
941            GCPP_2s (path),
942            GCC_2s (cc));
943       GCT_connection_lost (cc->ct);
944       GCC_destroy_without_tunnel (cc);
945     }
946     else
947     {
948       /* keep existing */
949       LOG (GNUNET_ERROR_TYPE_DEBUG,
950            "Got two connections on %s, keeping my existing %s\n",
951            GCPP_2s (path),
952            GCC_2s (cc));
953       return NULL;
954     }
955   }
956
957   return connection_create (destination,
958                             path,
959                             off,
960                             options,
961                             ct,
962                             cid,
963                             CADET_CONNECTION_CREATE_RECEIVED,
964                             ready_cb,
965                             ready_cb_cls);
966 }
967
968
969 /**
970  * Create a connection to @a destination via @a path and
971  * notify @a cb whenever we are ready for more data.
972  *
973  * @param destination where to go
974  * @param path which path to take (may not be the full path)
975  * @param off offset of @a destination on @a path
976  * @param options options for the connection
977  * @param ct tunnel that uses the connection
978  * @param ready_cb function to call when ready to transmit
979  * @param ready_cb_cls closure for @a cb
980  * @return handle to the connection
981  */
982 struct CadetConnection *
983 GCC_create (struct CadetPeer *destination,
984             struct CadetPeerPath *path,
985             unsigned int off,
986             enum GNUNET_CADET_ChannelOption options,
987             struct CadetTConnection *ct,
988             GCC_ReadyCallback ready_cb,
989             void *ready_cb_cls)
990 {
991   struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
992
993   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
994                               &cid,
995                               sizeof (cid));
996   return connection_create (destination,
997                             path,
998                             off,
999                             options,
1000                             ct,
1001                             &cid,
1002                             CADET_CONNECTION_NEW,
1003                             ready_cb,
1004                             ready_cb_cls);
1005 }
1006
1007
1008 /**
1009  * Transmit message @a msg via connection @a cc.  Must only be called
1010  * (once) after the connection has signalled that it is ready via the
1011  * `ready_cb`.  Clients can also use #GCC_is_ready() to check if the
1012  * connection is right now ready for transmission.
1013  *
1014  * @param cc connection identification
1015  * @param env envelope with message to transmit; must NOT
1016  *            yet have a #GNUNET_MQ_notify_sent() callback attached to it
1017  */
1018 void
1019 GCC_transmit (struct CadetConnection *cc,
1020               struct GNUNET_MQ_Envelope *env)
1021 {
1022   LOG (GNUNET_ERROR_TYPE_DEBUG,
1023        "Scheduling message for transmission on %s\n",
1024        GCC_2s (cc));
1025   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
1026   GNUNET_assert (CADET_CONNECTION_READY == cc->state);
1027   cc->metrics.last_use = GNUNET_TIME_absolute_get ();
1028   cc->mqm_ready = GNUNET_NO;
1029   if (NULL != cc->task)
1030   {
1031     GNUNET_SCHEDULER_cancel (cc->task);
1032     cc->task = NULL;
1033   }
1034   GCP_send (cc->mq_man,
1035             env);
1036 }
1037
1038
1039 /**
1040  * Obtain the path used by this connection.
1041  *
1042  * @param cc connection
1043  * @param off[out] set to the length of the path we use
1044  * @return path to @a cc
1045  */
1046 struct CadetPeerPath *
1047 GCC_get_path (struct CadetConnection *cc,
1048               unsigned int *off)
1049 {
1050   *off = cc->off;
1051   return cc->path;
1052 }
1053
1054
1055 /**
1056  * Obtain unique ID for the connection.
1057  *
1058  * @param cc connection.
1059  * @return unique number of the connection
1060  */
1061 const struct GNUNET_CADET_ConnectionTunnelIdentifier *
1062 GCC_get_id (struct CadetConnection *cc)
1063 {
1064   return &cc->cid;
1065 }
1066
1067
1068 /**
1069  * Get a (static) string for a connection.
1070  *
1071  * @param cc Connection.
1072  */
1073 const char *
1074 GCC_2s (const struct CadetConnection *cc)
1075 {
1076   static char buf[128];
1077
1078   if (NULL == cc)
1079     return "Connection(NULL)";
1080
1081   if (NULL != cc->ct)
1082   {
1083     GNUNET_snprintf (buf,
1084                      sizeof (buf),
1085                      "Connection %s (%s)",
1086                      GNUNET_sh2s (&cc->cid.connection_of_tunnel),
1087                      GCT_2s (cc->ct->t));
1088     return buf;
1089   }
1090   GNUNET_snprintf (buf,
1091                    sizeof (buf),
1092                    "Connection %s",
1093                    GNUNET_sh2s (&cc->cid.connection_of_tunnel));
1094   return buf;
1095 }
1096
1097
1098 #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-con",__VA_ARGS__)
1099
1100
1101 /**
1102  * Log connection info.
1103  *
1104  * @param cc connection
1105  * @param level Debug level to use.
1106  */
1107 void
1108 GCC_debug (struct CadetConnection *cc,
1109            enum GNUNET_ErrorType level)
1110 {
1111 #if !defined(GNUNET_CULL_LOGGING)
1112   int do_log;
1113
1114   do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
1115                                        "cadet-con",
1116                                        __FILE__, __FUNCTION__, __LINE__);
1117   if (0 == do_log)
1118     return;
1119   if (NULL == cc)
1120   {
1121     LOG2 (level,
1122           "Connection (NULL)\n");
1123     return;
1124   }
1125   LOG2 (level,
1126         "%s to %s via path %s in state %d is %s\n",
1127         GCC_2s (cc),
1128         GCP_2s (cc->destination),
1129         GCPP_2s (cc->path),
1130         cc->state,
1131         (GNUNET_YES == cc->mqm_ready) ? "ready" : "busy");
1132 #endif
1133 }
1134
1135 /* end of gnunet-service-cadet_connection.c */