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