introduce buffering options on the route level
[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  * TODO:
29  * - keep per-connection performance metrics
30  * - in particular, interact with channel (!) to see
31  *   if we get ACKs indicating successful payload delivery.
32  */
33 #include "platform.h"
34 #include "gnunet-service-cadet-new.h"
35 #include "gnunet-service-cadet-new_channel.h"
36 #include "gnunet-service-cadet-new_connection.h"
37 #include "gnunet-service-cadet-new_paths.h"
38 #include "gnunet-service-cadet-new_peer.h"
39 #include "gnunet-service-cadet-new_tunnels.h"
40 #include "gnunet_cadet_service.h"
41 #include "gnunet_statistics_service.h"
42 #include "cadet_protocol.h"
43
44
45 #define LOG(level, ...) GNUNET_log_from(level,"cadet-con",__VA_ARGS__)
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    * 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    * Offset of our @e destination in @e path.
155    */
156   unsigned int off;
157
158   /**
159    * Are we ready to transmit via @e mq_man right now?
160    */
161   int mqm_ready;
162
163 };
164
165
166 /**
167  * Update the connection state. Also triggers the necessary
168  * MQM notifications.
169  *
170  * @param cc connection to update the state for
171  * @param new_state new state for @a cc
172  * @param new_mqm_ready new `mqm_ready` state for @a cc
173  */
174 static void
175 update_state (struct CadetConnection *cc,
176               enum CadetConnectionState new_state,
177               int new_mqm_ready)
178 {
179   int old_ready;
180   int new_ready;
181
182   if ( (new_state == cc->state) &&
183        (new_mqm_ready == cc->mqm_ready) )
184     return; /* no change, nothing to do */
185   old_ready = ( (CADET_CONNECTION_READY == cc->state) &&
186                 (GNUNET_YES == cc->mqm_ready) );
187   new_ready = ( (CADET_CONNECTION_READY == new_state) &&
188                 (GNUNET_YES == new_mqm_ready) );
189   cc->state = new_state;
190   cc->mqm_ready = new_mqm_ready;
191   if (old_ready != new_ready)
192     cc->ready_cb (cc->ready_cb_cls,
193                   new_ready);
194 }
195
196
197 /**
198  * Destroy a connection, part of the internal implementation.  Called
199  * only from #GCC_destroy_from_core() or #GCC_destroy_from_tunnel().
200  *
201  * @param cc connection to destroy
202  */
203 static void
204 GCC_destroy (struct CadetConnection *cc)
205 {
206   LOG (GNUNET_ERROR_TYPE_DEBUG,
207        "Destroying %s\n",
208        GCC_2s (cc));
209   if (NULL != cc->mq_man)
210   {
211     GCP_request_mq_cancel (cc->mq_man,
212                            NULL);
213     cc->mq_man = NULL;
214   }
215   if (NULL != cc->task)
216   {
217     GNUNET_SCHEDULER_cancel (cc->task);
218     cc->task = NULL;
219   }
220   if (NULL != cc->keepalive_qe)
221   {
222     GCT_send_cancel (cc->keepalive_qe);
223     cc->keepalive_qe = NULL;
224   }
225   GCPP_del_connection (cc->path,
226                        cc->off,
227                        cc);
228   GNUNET_assert (GNUNET_YES ==
229                  GNUNET_CONTAINER_multishortmap_remove (connections,
230                                                         &GCC_get_id (cc)->connection_of_tunnel,
231                                                         cc));
232   GNUNET_free (cc);
233 }
234
235
236
237 /**
238  * Destroy a connection, called when the CORE layer is already done
239  * (i.e. has received a BROKEN message), but if we still have to
240  * communicate the destruction of the connection to the tunnel (if one
241  * exists).
242  *
243  * @param cc connection to destroy
244  */
245 void
246 GCC_destroy_without_core (struct CadetConnection *cc)
247 {
248   if (NULL != cc->ct)
249   {
250     GCT_connection_lost (cc->ct);
251     cc->ct = NULL;
252   }
253   GCC_destroy (cc);
254 }
255
256
257 /**
258  * Destroy a connection, called if the tunnel association with the
259  * connection was already broken, but we still need to notify the CORE
260  * layer about the breakage.
261  *
262  * @param cc connection to destroy
263  */
264 void
265 GCC_destroy_without_tunnel (struct CadetConnection *cc)
266 {
267   cc->ct = NULL;
268   if ( (CADET_CONNECTION_SENDING_CREATE != cc->state) &&
269        (NULL != cc->mq_man) )
270   {
271     struct GNUNET_MQ_Envelope *env;
272     struct GNUNET_CADET_ConnectionDestroyMessage *destroy_msg;
273
274     /* Need to notify next hop that we are down. */
275     env = GNUNET_MQ_msg (destroy_msg,
276                          GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY);
277     destroy_msg->cid = cc->cid;
278     GCP_request_mq_cancel (cc->mq_man,
279                            env);
280     cc->mq_man = NULL;
281   }
282   GCC_destroy (cc);
283 }
284
285
286 /**
287  * Return the tunnel associated with this connection.
288  *
289  * @param cc connection to query
290  * @return corresponding entry in the tunnel's connection list
291  */
292 struct CadetTConnection *
293 GCC_get_ct (struct CadetConnection *cc)
294 {
295   return cc->ct;
296 }
297
298
299 /**
300  * Send a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE through the
301  * tunnel to prevent it from timing out.
302  *
303  * @param cls the `struct CadetConnection` to keep alive.
304  */
305 static void
306 send_keepalive (void *cls);
307
308
309 /**
310  * Keepalive was transmitted.  Remember this, and possibly
311  * schedule the next one.
312  *
313  * @param cls the `struct CadetConnection` to keep alive.
314  */
315 static void
316 keepalive_done (void *cls)
317 {
318   struct CadetConnection *cc = cls;
319
320   cc->keepalive_qe = NULL;
321   if ( (GNUNET_YES == cc->mqm_ready) &&
322        (NULL == cc->task) )
323     cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
324                                              &send_keepalive,
325                                              cc);
326 }
327
328
329 /**
330  * Send a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE through the
331  * tunnel to prevent it from timing out.
332  *
333  * @param cls the `struct CadetConnection` to keep alive.
334  */
335 static void
336 send_keepalive (void *cls)
337 {
338   struct CadetConnection *cc = cls;
339   struct GNUNET_MessageHeader msg;
340
341   cc->task = NULL;
342   if (CADET_TUNNEL_KEY_OK != GCT_get_estate (cc->ct->t))
343   {
344     /* Tunnel not yet ready, wait with keepalives... */
345     cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
346                                              &send_keepalive,
347                                              cc);
348     return;
349   }
350   GNUNET_assert (NULL != cc->ct);
351   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
352   GNUNET_assert (NULL == cc->keepalive_qe);
353   LOG (GNUNET_ERROR_TYPE_INFO,
354        "Sending KEEPALIVE on behalf of %s via %s\n",
355        GCC_2s (cc),
356        GCT_2s (cc->ct->t));
357   GNUNET_STATISTICS_update (stats,
358                             "# keepalives sent",
359                             1,
360                             GNUNET_NO);
361   msg.size = htons (sizeof (msg));
362   msg.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE);
363
364   cc->keepalive_qe
365     = GCT_send (cc->ct->t,
366                 &msg,
367                 &keepalive_done,
368                 cc);
369 }
370
371
372 /**
373  * A #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK was received for this connection, implying
374  * that the end-to-end connection is up.  Process it.
375  *
376  * @param cc the connection that got the ACK.
377  */
378 void
379 GCC_handle_connection_create_ack (struct CadetConnection *cc)
380 {
381   LOG (GNUNET_ERROR_TYPE_DEBUG,
382        "Received CADET_CONNECTION_CREATE_ACK for %s in state %d (%s)\n",
383        GCC_2s (cc),
384        cc->state,
385        (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy");
386   if (CADET_CONNECTION_READY == cc->state)
387     return; /* Duplicate ACK, ignore */
388   if (NULL != cc->task)
389   {
390     GNUNET_SCHEDULER_cancel (cc->task);
391     cc->task = NULL;
392   }
393   update_state (cc,
394                 CADET_CONNECTION_READY,
395                 cc->mqm_ready);
396   if ( (NULL == cc->keepalive_qe) &&
397        (GNUNET_YES == cc->mqm_ready) &&
398        (NULL == cc->task) )
399     cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
400                                              &send_keepalive,
401                                              cc);
402 }
403
404
405 /**
406  * Handle KX message.
407  *
408  * @param cc connection that received encrypted message
409  * @param msg the key exchange message
410  */
411 void
412 GCC_handle_kx (struct CadetConnection *cc,
413                const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
414 {
415   if (CADET_CONNECTION_SENT == cc->state)
416   {
417     /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
418        clearly something is working, so pretend we got an ACK. */
419     LOG (GNUNET_ERROR_TYPE_DEBUG,
420          "Faking connection CADET_CONNECTION_CREATE_ACK for %s due to KX\n",
421          GCC_2s (cc));
422     GCC_handle_connection_create_ack (cc);
423   }
424   GCT_handle_kx (cc->ct,
425                  msg);
426 }
427
428
429 /**
430  * Handle KX_AUTH message.
431  *
432  * @param cc connection that received encrypted message
433  * @param msg the key exchange message
434  */
435 void
436 GCC_handle_kx_auth (struct CadetConnection *cc,
437                     const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
438 {
439   if (CADET_CONNECTION_SENT == cc->state)
440   {
441     /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
442        clearly something is working, so pretend we got an ACK. */
443     LOG (GNUNET_ERROR_TYPE_DEBUG,
444          "Faking connection CADET_CONNECTION_CREATE_ACK for %s due to KX\n",
445          GCC_2s (cc));
446     GCC_handle_connection_create_ack (cc);
447   }
448   GCT_handle_kx_auth (cc->ct,
449                       msg);
450 }
451
452
453 /**
454  * Handle encrypted message.
455  *
456  * @param cc connection that received encrypted message
457  * @param msg the encrypted message to decrypt
458  */
459 void
460 GCC_handle_encrypted (struct CadetConnection *cc,
461                       const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
462 {
463   if (CADET_CONNECTION_SENT == cc->state)
464   {
465     /* We didn't get the CREATE_ACK, but instead got payload. That's fine,
466        clearly something is working, so pretend we got an ACK. */
467     LOG (GNUNET_ERROR_TYPE_DEBUG,
468          "Faking connection ACK for %s due to ENCRYPTED payload\n",
469          GCC_2s (cc));
470     GCC_handle_connection_create_ack (cc);
471   }
472   GCT_handle_encrypted (cc->ct,
473                         msg);
474 }
475
476
477 /**
478  * Send a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE message to the
479  * first hop.
480  *
481  * @param cls the `struct CadetConnection` to initiate
482  */
483 static void
484 send_create (void *cls)
485 {
486   struct CadetConnection *cc = cls;
487   struct GNUNET_CADET_ConnectionCreateMessage *create_msg;
488   struct GNUNET_PeerIdentity *pids;
489   struct GNUNET_MQ_Envelope *env;
490   unsigned int path_length;
491
492   cc->task = NULL;
493   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
494   path_length = GCPP_get_length (cc->path);
495   env = GNUNET_MQ_msg_extra (create_msg,
496                              (1 + path_length) * sizeof (struct GNUNET_PeerIdentity),
497                              GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
498   create_msg->options = htonl ((uint32_t) cc->options);
499   create_msg->cid = cc->cid;
500   pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
501   pids[0] = my_full_id;
502   for (unsigned int i=0;i<path_length;i++)
503     pids[i + 1] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
504                                                         i));
505   LOG (GNUNET_ERROR_TYPE_DEBUG,
506        "Sending CADET_CONNECTION_CREATE message for %s\n",
507        GCC_2s (cc));
508   cc->env = env;
509   update_state (cc,
510                 CADET_CONNECTION_SENT,
511                 GNUNET_NO);
512   GCP_send (cc->mq_man,
513             env);
514 }
515
516
517 /**
518  * Send a CREATE_ACK message towards the origin.
519  *
520  * @param cls the `struct CadetConnection` to initiate
521  */
522 static void
523 send_create_ack (void *cls)
524 {
525   struct CadetConnection *cc = cls;
526   struct GNUNET_CADET_ConnectionCreateAckMessage *ack_msg;
527   struct GNUNET_MQ_Envelope *env;
528
529   cc->task = NULL;
530   GNUNET_assert (CADET_CONNECTION_CREATE_RECEIVED == cc->state);
531   LOG (GNUNET_ERROR_TYPE_DEBUG,
532        "Sending CONNECTION_CREATE_ACK message for %s\n",
533        GCC_2s (cc));
534   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
535   env = GNUNET_MQ_msg (ack_msg,
536                        GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK);
537   ack_msg->cid = cc->cid;
538   cc->env = env;
539   update_state (cc,
540                 CADET_CONNECTION_READY,
541                 GNUNET_NO);
542   GCP_send (cc->mq_man,
543             env);
544 }
545
546
547 /**
548  * We got a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a
549  * connection that we already have.  Either our ACK got lost
550  * or something is fishy.  Consider retransmitting the ACK.
551  *
552  * @param cc connection that got the duplicate CREATE
553  */
554 void
555 GCC_handle_duplicate_create (struct CadetConnection *cc)
556 {
557   if (GNUNET_YES == cc->mqm_ready)
558   {
559     LOG (GNUNET_ERROR_TYPE_DEBUG,
560          "Got duplicate CREATE for %s, scheduling another ACK (%s)\n",
561          GCC_2s (cc),
562          (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy");
563     /* Revert back to the state of having only received the 'CREATE',
564        and immediately proceed to send the CREATE_ACK. */
565     update_state (cc,
566                   CADET_CONNECTION_CREATE_RECEIVED,
567                   cc->mqm_ready);
568     if (NULL != cc->task)
569       GNUNET_SCHEDULER_cancel (cc->task);
570     cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
571                                          cc);
572   }
573   else
574   {
575     /* We are currently sending something else back, which
576        can only be an ACK or payload, either of which would
577        do. So actually no need to do anything. */
578     LOG (GNUNET_ERROR_TYPE_DEBUG,
579          "Got duplicate CREATE for %s. MQ is busy, not queueing another ACK\n",
580          GCC_2s (cc));
581   }
582 }
583
584
585 /**
586  * There has been a change in the message queue existence for our
587  * peer at the first hop.  Adjust accordingly.
588  *
589  * @param cls the `struct CadetConnection`
590  * @param available #GNUNET_YES if sending is now possible,
591  *                  #GNUNET_NO if sending is no longer possible
592  *                  #GNUNET_SYSERR if sending is no longer possible
593  *                                 and the last envelope was discarded
594  */
595 static void
596 manage_first_hop_mq (void *cls,
597                      int available)
598 {
599   struct CadetConnection *cc = cls;
600
601   if (GNUNET_YES != available)
602   {
603     /* Connection is down, for now... */
604     LOG (GNUNET_ERROR_TYPE_DEBUG,
605          "Core MQ for %s went down\n",
606          GCC_2s (cc));
607     update_state (cc,
608                   CADET_CONNECTION_NEW,
609                   GNUNET_NO);
610     cc->retry_delay = GNUNET_TIME_UNIT_ZERO;
611     if (NULL != cc->task)
612     {
613       GNUNET_SCHEDULER_cancel (cc->task);
614       cc->task = NULL;
615     }
616     return;
617   }
618
619   update_state (cc,
620                 cc->state,
621                 GNUNET_YES);
622   LOG (GNUNET_ERROR_TYPE_DEBUG,
623        "Core MQ for %s became available in state %d\n",
624        GCC_2s (cc),
625        cc->state);
626   switch (cc->state)
627   {
628   case CADET_CONNECTION_NEW:
629     /* Transmit immediately */
630     cc->task = GNUNET_SCHEDULER_add_now (&send_create,
631                                          cc);
632     break;
633   case CADET_CONNECTION_SENDING_CREATE:
634     /* Should not be possible to be called in this state. */
635     GNUNET_assert (0);
636     break;
637   case CADET_CONNECTION_SENT:
638     /* Retry a bit later... */
639     cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
640     cc->task = GNUNET_SCHEDULER_add_delayed (cc->retry_delay,
641                                              &send_create,
642                                              cc);
643     break;
644   case CADET_CONNECTION_CREATE_RECEIVED:
645     /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */
646     cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
647                                          cc);
648     break;
649   case CADET_CONNECTION_READY:
650     if ( (NULL == cc->keepalive_qe) &&
651          (GNUNET_YES == cc->mqm_ready) &&
652          (NULL == cc->task) )
653     {
654       LOG (GNUNET_ERROR_TYPE_DEBUG,
655            "Scheduling keepalive for %s in %s\n",
656            GCC_2s (cc),
657            GNUNET_STRINGS_relative_time_to_string (keepalive_period,
658                                                    GNUNET_YES));
659       cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
660                                                &send_keepalive,
661                                                cc);
662     }
663     break;
664   }
665 }
666
667
668 /**
669  * Create a connection to @a destination via @a path and notify @a cb
670  * whenever we are ready for more data.  Shared logic independent of
671  * who is initiating the connection.
672  *
673  * @param destination where to go
674  * @param path which path to take (may not be the full path)
675  * @param options options for the connection
676  * @param ct which tunnel uses this connection
677  * @param init_state initial state for the connection
678  * @param ready_cb function to call when ready to transmit
679  * @param ready_cb_cls closure for @a cb
680  * @return handle to the connection
681  */
682 static struct CadetConnection *
683 connection_create (struct CadetPeer *destination,
684                    struct CadetPeerPath *path,
685                    enum GNUNET_CADET_ChannelOption options,
686                    struct CadetTConnection *ct,
687                    const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
688                    enum CadetConnectionState init_state,
689                    GCC_ReadyCallback ready_cb,
690                    void *ready_cb_cls)
691 {
692   struct CadetConnection *cc;
693   struct CadetPeer *first_hop;
694   unsigned int off;
695
696   off = GCPP_find_peer (path,
697                         destination);
698   GNUNET_assert (UINT_MAX > off);
699   cc = GNUNET_new (struct CadetConnection);
700   cc->options = options;
701   cc->state = init_state;
702   cc->ct = ct;
703   cc->cid = *cid;
704   GNUNET_assert (GNUNET_OK ==
705                  GNUNET_CONTAINER_multishortmap_put (connections,
706                                                      &GCC_get_id (cc)->connection_of_tunnel,
707                                                      cc,
708                                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
709   cc->ready_cb = ready_cb;
710   cc->ready_cb_cls = ready_cb_cls;
711   cc->path = path;
712   cc->off = off;
713   LOG (GNUNET_ERROR_TYPE_DEBUG,
714        "Creating %s using path %s\n",
715        GCC_2s (cc),
716        GCPP_2s (path));
717   GCPP_add_connection (path,
718                        off,
719                        cc);
720   for (unsigned int i=0;i<off;i++)
721     GCP_add_connection (GCPP_get_peer_at_offset (path,
722                                                  off),
723                         cc);
724
725   first_hop = GCPP_get_peer_at_offset (path,
726                                        0);
727   cc->mq_man = GCP_request_mq (first_hop,
728                                &manage_first_hop_mq,
729                                cc);
730   return cc;
731 }
732
733
734 /**
735  * Create a connection to @a destination via @a path and
736  * notify @a cb whenever we are ready for more data.  This
737  * is an inbound tunnel, so we must use the existing @a cid
738  *
739  * @param destination where to go
740  * @param path which path to take (may not be the full path)
741  * @param options options for the connection
742  * @param ct which tunnel uses this connection
743  * @param ready_cb function to call when ready to transmit
744  * @param ready_cb_cls closure for @a cb
745  * @return handle to the connection, NULL if we already have
746  *         a connection that takes precedence on @a path
747  */
748 struct CadetConnection *
749 GCC_create_inbound (struct CadetPeer *destination,
750                     struct CadetPeerPath *path,
751                    enum GNUNET_CADET_ChannelOption options,
752                     struct CadetTConnection *ct,
753                     const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
754                     GCC_ReadyCallback ready_cb,
755                     void *ready_cb_cls)
756 {
757   struct CadetConnection *cc;
758   unsigned int off;
759
760   off = GCPP_find_peer (path,
761                         destination);
762   GNUNET_assert (UINT_MAX != off);
763   cc = GCPP_get_connection (path,
764                             destination,
765                             off);
766   if (NULL != cc)
767   {
768     int cmp;
769
770     cmp = memcmp (cid,
771                   &cc->cid,
772                   sizeof (*cid));
773     if (0 == cmp)
774     {
775       /* Two peers picked the SAME random connection identifier at the
776          same time for the same path? Must be malicious.  Drop
777          connection (existing and inbound), even if it is the only
778          one. */
779       GNUNET_break_op (0);
780       GCT_connection_lost (cc->ct);
781       GCC_destroy_without_tunnel (cc);
782       return NULL;
783     }
784     if (0 < cmp)
785     {
786       /* drop existing */
787       LOG (GNUNET_ERROR_TYPE_DEBUG,
788            "Got two connections on %s, dropping my existing %s\n",
789            GCPP_2s (path),
790            GCC_2s (cc));
791       GCT_connection_lost (cc->ct);
792       GCC_destroy_without_tunnel (cc);
793     }
794     else
795     {
796       /* keep existing */
797       LOG (GNUNET_ERROR_TYPE_DEBUG,
798            "Got two connections on %s, keeping my existing %s\n",
799            GCPP_2s (path),
800            GCC_2s (cc));
801       return NULL;
802     }
803   }
804
805   return connection_create (destination,
806                             path,
807                             options,
808                             ct,
809                             cid,
810                             CADET_CONNECTION_CREATE_RECEIVED,
811                             ready_cb,
812                             ready_cb_cls);
813 }
814
815
816 /**
817  * Create a connection to @a destination via @a path and
818  * notify @a cb whenever we are ready for more data.
819  *
820  * @param destination where to go
821  * @param path which path to take (may not be the full path)
822  * @param options options for the connection
823  * @param ct tunnel that uses the connection
824  * @param ready_cb function to call when ready to transmit
825  * @param ready_cb_cls closure for @a cb
826  * @return handle to the connection
827  */
828 struct CadetConnection *
829 GCC_create (struct CadetPeer *destination,
830             struct CadetPeerPath *path,
831             enum GNUNET_CADET_ChannelOption options,
832             struct CadetTConnection *ct,
833             GCC_ReadyCallback ready_cb,
834             void *ready_cb_cls)
835 {
836   struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
837
838   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
839                               &cid,
840                               sizeof (cid));
841   return connection_create (destination,
842                             path,
843                             options,
844                             ct,
845                             &cid,
846                             CADET_CONNECTION_NEW,
847                             ready_cb,
848                             ready_cb_cls);
849 }
850
851
852 /**
853  * Transmit message @a msg via connection @a cc.  Must only be called
854  * (once) after the connection has signalled that it is ready via the
855  * `ready_cb`.  Clients can also use #GCC_is_ready() to check if the
856  * connection is right now ready for transmission.
857  *
858  * @param cc connection identification
859  * @param env envelope with message to transmit; must NOT
860  *            yet have a #GNUNET_MQ_notify_sent() callback attached to it
861  */
862 void
863 GCC_transmit (struct CadetConnection *cc,
864               struct GNUNET_MQ_Envelope *env)
865 {
866   LOG (GNUNET_ERROR_TYPE_DEBUG,
867        "Scheduling message for transmission on %s\n",
868        GCC_2s (cc));
869   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
870   GNUNET_assert (CADET_CONNECTION_READY == cc->state);
871   cc->mqm_ready = GNUNET_NO;
872   if (NULL != cc->task)
873   {
874     GNUNET_SCHEDULER_cancel (cc->task);
875     cc->task = NULL;
876   }
877   GCP_send (cc->mq_man,
878             env);
879 }
880
881
882 /**
883  * Obtain the path used by this connection.
884  *
885  * @param cc connection
886  * @return path to @a cc
887  */
888 struct CadetPeerPath *
889 GCC_get_path (struct CadetConnection *cc)
890 {
891   return cc->path;
892 }
893
894
895 /**
896  * Obtain unique ID for the connection.
897  *
898  * @param cc connection.
899  * @return unique number of the connection
900  */
901 const struct GNUNET_CADET_ConnectionTunnelIdentifier *
902 GCC_get_id (struct CadetConnection *cc)
903 {
904   return &cc->cid;
905 }
906
907
908 /**
909  * Get a (static) string for a connection.
910  *
911  * @param cc Connection.
912  */
913 const char *
914 GCC_2s (const struct CadetConnection *cc)
915 {
916   static char buf[128];
917
918   if (NULL == cc)
919     return "Connection(NULL)";
920
921   if (NULL != cc->ct)
922   {
923     GNUNET_snprintf (buf,
924                      sizeof (buf),
925                      "Connection %s (%s)",
926                      GNUNET_sh2s (&cc->cid.connection_of_tunnel),
927                      GCT_2s (cc->ct->t));
928     return buf;
929   }
930   GNUNET_snprintf (buf,
931                    sizeof (buf),
932                    "Connection %s",
933                    GNUNET_sh2s (&cc->cid.connection_of_tunnel));
934   return buf;
935 }
936
937
938 #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-con",__VA_ARGS__)
939
940
941 /**
942  * Log connection info.
943  *
944  * @param cc connection
945  * @param level Debug level to use.
946  */
947 void
948 GCC_debug (struct CadetConnection *cc,
949            enum GNUNET_ErrorType level)
950 {
951   int do_log;
952
953   do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
954                                        "cadet-con",
955                                        __FILE__, __FUNCTION__, __LINE__);
956   if (0 == do_log)
957     return;
958   if (NULL == cc)
959   {
960     LOG2 (level,
961           "Connection (NULL)\n");
962     return;
963   }
964   LOG2 (level,
965         "%s to %s via path %s in state %d is %s\n",
966         GCC_2s (cc),
967         GCP_2s (cc->destination),
968         GCPP_2s (cc->path),
969         cc->state,
970         (GNUNET_YES == cc->mqm_ready) ? "ready" : "busy");
971 }
972
973 /* end of gnunet-service-cadet-new_connection.c */