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