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