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