implement get_path_from_route
[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: keepalive messages / timeout (timeout to be done @ peer level!)
31  * - Optimization: keep performance metrics (?)
32  */
33 #include "platform.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 "cadet_protocol.h"
41
42
43 #define LOG(level, ...) GNUNET_log_from(level,"cadet-con",__VA_ARGS__)
44
45
46 /**
47  * All the states a connection can be in.
48  */
49 enum CadetConnectionState
50 {
51   /**
52    * Uninitialized status, we have not yet even gotten the message queue.
53    */
54   CADET_CONNECTION_NEW,
55
56   /**
57    * Connection create message in queue, awaiting transmission by CORE.
58    */
59   CADET_CONNECTION_SENDING_CREATE,
60
61   /**
62    * Connection create message sent, waiting for ACK.
63    */
64   CADET_CONNECTION_SENT,
65
66   /**
67    * We are an inbound connection, and received a CREATE. Need to
68    * send an CREATE_ACK back.
69    */
70   CADET_CONNECTION_CREATE_RECEIVED,
71
72   /**
73    * Connection confirmed, ready to carry traffic.
74    */
75   CADET_CONNECTION_READY
76
77 };
78
79
80 /**
81  * Low-level connection to a destination.
82  */
83 struct CadetConnection
84 {
85
86   /**
87    * ID of the connection.
88    */
89   struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
90
91   /**
92    * To which peer does this connection go?
93    */
94   struct CadetPeer *destination;
95
96   /**
97    * Which tunnel is using this connection?
98    */
99   struct CadetTConnection *ct;
100
101   /**
102    * Path we are using to our destination.
103    */
104   struct CadetPeerPath *path;
105
106   /**
107    * Pending message, NULL if we are ready to transmit.
108    */
109   struct GNUNET_MQ_Envelope *env;
110
111   /**
112    * Handle for calling #GCP_request_mq_cancel() once we are finished.
113    */
114   struct GCP_MessageQueueManager *mq_man;
115
116   /**
117    * Task for connection maintenance.
118    */
119   struct GNUNET_SCHEDULER_Task *task;
120
121   /**
122    * Function to call once we are ready to transmit.
123    */
124   GCC_ReadyCallback ready_cb;
125
126   /**
127    * Closure for @e ready_cb.
128    */
129   void *ready_cb_cls;
130
131   /**
132    * How long do we wait before we try again with a CREATE message?
133    */
134   struct GNUNET_TIME_Relative retry_delay;
135
136   /**
137    * State of the connection.
138    */
139   enum CadetConnectionState state;
140
141   /**
142    * Offset of our @e destination in @e path.
143    */
144   unsigned int off;
145
146   /**
147    * Are we ready to transmit via @e mq_man right now?
148    */
149   int mqm_ready;
150
151 };
152
153
154 /**
155  * Destroy a connection.
156  *
157  * @param cc connection to destroy
158  */
159 void
160 GCC_destroy (struct CadetConnection *cc)
161 {
162   struct GNUNET_MQ_Envelope *env = NULL;
163
164   LOG (GNUNET_ERROR_TYPE_DEBUG,
165        "Destroying connection %s\n",
166        GCC_2s (cc));
167   if (CADET_CONNECTION_SENDING_CREATE != cc->state)
168   {
169     struct GNUNET_CADET_ConnectionDestroyMessage *destroy_msg;
170
171     /* Need to notify next hop that we are down. */
172     env = GNUNET_MQ_msg (destroy_msg,
173                          GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY);
174     destroy_msg->cid = cc->cid;
175   }
176   GCP_request_mq_cancel (cc->mq_man,
177                          env);
178   cc->mq_man = NULL;
179   GCPP_del_connection (cc->path,
180                        cc->off,
181                        cc);
182   GNUNET_assert (GNUNET_YES ==
183                  GNUNET_CONTAINER_multishortmap_remove (connections,
184                                                         &GCC_get_id (cc)->connection_of_tunnel,
185                                                         cc));
186   GNUNET_free (cc);
187 }
188
189
190 /**
191  * Return the tunnel associated with this connection.
192  *
193  * @param cc connection to query
194  * @return corresponding entry in the tunnel's connection list
195  */
196 struct CadetTConnection *
197 GCC_get_ct (struct CadetConnection *cc)
198 {
199   return cc->ct;
200 }
201
202
203 /**
204  * A connection ACK was received for this connection, implying
205  * that the end-to-end connection is up.  Process it.
206  *
207  * @param cc the connection that got the ACK.
208  */
209 void
210 GCC_handle_connection_create_ack (struct CadetConnection *cc)
211 {
212   LOG (GNUNET_ERROR_TYPE_DEBUG,
213        "Received CREATE_ACK for connection %s in state %d\n",
214        GCC_2s (cc),
215        cc->state);
216   if (NULL != cc->task)
217   {
218     GNUNET_SCHEDULER_cancel (cc->task);
219     cc->task = NULL;
220   }
221 #if FIXME_KEEPALIVE
222   cc->task = GNUNET_SCHEDULER_add_delayed (cc->keepalive_period,
223                                            &send_keepalive,
224                                            cc);
225 #endif
226   cc->state = CADET_CONNECTION_READY;
227   if (GNUNET_YES == cc->mqm_ready)
228     cc->ready_cb (cc->ready_cb_cls,
229                   GNUNET_YES);
230 }
231
232
233 /**
234  * Handle KX message.
235  *
236  * @param cc connection that received encrypted message
237  * @param msg the key exchange message
238  */
239 void
240 GCC_handle_kx (struct CadetConnection *cc,
241                const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
242 {
243   if (CADET_CONNECTION_SENT == cc->state)
244   {
245     /* We didn't get the CREATE_ACK, but instead got payload. That's fine,
246        clearly something is working, so pretend we got an ACK. */
247     LOG (GNUNET_ERROR_TYPE_DEBUG,
248          "Faking connection ACK for connection %s due to KX\n",
249          GCC_2s (cc));
250     GCC_handle_connection_create_ack (cc);
251   }
252   GCT_handle_kx (cc->ct,
253                  msg);
254 }
255
256
257 /**
258  * Handle encrypted message.
259  *
260  * @param cc connection that received encrypted message
261  * @param msg the encrypted message to decrypt
262  */
263 void
264 GCC_handle_encrypted (struct CadetConnection *cc,
265                       const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
266 {
267   if (CADET_CONNECTION_SENT == cc->state)
268   {
269     /* We didn't get the CREATE_ACK, but instead got payload. That's fine,
270        clearly something is working, so pretend we got an ACK. */
271     LOG (GNUNET_ERROR_TYPE_DEBUG,
272          "Faking connection ACK for connection %s due to ENCRYPTED payload\n",
273          GCC_2s (cc));
274     GCC_handle_connection_create_ack (cc);
275   }
276   GCT_handle_encrypted (cc->ct,
277                         msg);
278 }
279
280
281 /**
282  * Send a CREATE message to the first hop.
283  *
284  * @param cls the `struct CadetConnection` to initiate
285  */
286 static void
287 send_create (void *cls)
288 {
289   struct CadetConnection *cc = cls;
290   struct GNUNET_CADET_ConnectionCreateMessage *create_msg;
291   struct GNUNET_PeerIdentity *pids;
292   struct GNUNET_MQ_Envelope *env;
293   unsigned int path_length;
294
295   cc->task = NULL;
296   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
297   path_length = GCPP_get_length (cc->path) + 1;
298   env = GNUNET_MQ_msg_extra (create_msg,
299                              path_length * sizeof (struct GNUNET_PeerIdentity),
300                              GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
301   create_msg->cid = cc->cid;
302   pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
303   pids[0] = my_full_id;
304   for (unsigned int i=1;i<=path_length;i++)
305     pids[i] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
306                                                     i - 1));
307   LOG (GNUNET_ERROR_TYPE_DEBUG,
308        "Sending CONNECTION_CREATE message for connection %s\n",
309        GCC_2s (cc));
310   cc->env = env;
311   cc->mqm_ready = GNUNET_NO;
312   cc->state = CADET_CONNECTION_SENT;
313   GCP_send (cc->mq_man,
314             env);
315 }
316
317
318 /**
319  * Send a CREATE_ACK message towards the origin.
320  *
321  * @param cls the `struct CadetConnection` to initiate
322  */
323 static void
324 send_create_ack (void *cls)
325 {
326   struct CadetConnection *cc = cls;
327   struct GNUNET_CADET_ConnectionCreateAckMessage *ack_msg;
328   struct GNUNET_MQ_Envelope *env;
329
330   cc->task = NULL;
331   LOG (GNUNET_ERROR_TYPE_DEBUG,
332        "Sending CONNECTION_CREATE_ACK message for connection %s\n",
333        GCC_2s (cc));
334   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
335   env = GNUNET_MQ_msg (ack_msg,
336                        GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK);
337   ack_msg->cid = cc->cid;
338   cc->env = env;
339   cc->mqm_ready = GNUNET_NO;
340   cc->state = CADET_CONNECTION_READY;
341   GCP_send (cc->mq_man,
342             env);
343 }
344
345
346 /**
347  * We got a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a
348  * connection that we already have.  Either our ACK got lost
349  * or something is fishy.  Consider retransmitting the ACK.
350  *
351  * @param cc connection that got the duplicate CREATE
352  */
353 void
354 GCC_handle_duplicate_create (struct CadetConnection *cc)
355 {
356   if (GNUNET_YES == cc->mqm_ready)
357   {
358     LOG (GNUNET_ERROR_TYPE_DEBUG,
359          "Got duplicate CREATE for connection %s, scheduling another ACK\n",
360          GCC_2s (cc));
361     /* Tell tunnel that we are not ready for transmission anymore
362        (until CREATE_ACK is done) */
363     cc->ready_cb (cc->ready_cb_cls,
364                   GNUNET_NO);
365     /* Revert back to the state of having only received the 'CREATE',
366        and immediately proceed to send the CREATE_ACK. */
367     cc->state = CADET_CONNECTION_CREATE_RECEIVED;
368     cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
369                                          cc);
370   }
371   else
372   {
373     /* We are currently sending something else back, which
374        can only be an ACK or payload, either of which would
375        do. So actually no need to do anything. */
376     LOG (GNUNET_ERROR_TYPE_DEBUG,
377          "Got duplicate CREATE for connection %s. MQ is busy, not queueing another ACK\n",
378          GCC_2s (cc));
379   }
380 }
381
382
383 /**
384  * There has been a change in the message queue existence for our
385  * peer at the first hop.  Adjust accordingly.
386  *
387  * @param cls the `struct CadetConnection`
388  * @param available #GNUNET_YES if sending is now possible,
389  *                  #GNUNET_NO if sending is no longer possible
390  *                  #GNUNET_SYSERR if sending is no longer possible
391  *                                 and the last envelope was discarded
392  */
393 static void
394 manage_first_hop_mq (void *cls,
395                      int available)
396 {
397   struct CadetConnection *cc = cls;
398
399   if (GNUNET_YES != available)
400   {
401     /* Connection is down, for now... */
402     LOG (GNUNET_ERROR_TYPE_DEBUG,
403          "Core MQ for connection %s went down\n",
404          GCC_2s (cc));
405     cc->mqm_ready = GNUNET_NO;
406     cc->state = CADET_CONNECTION_NEW;
407     cc->retry_delay = GNUNET_TIME_UNIT_ZERO;
408     if (NULL != cc->task)
409     {
410       GNUNET_SCHEDULER_cancel (cc->task);
411       cc->task = NULL;
412     }
413     cc->ready_cb (cc->ready_cb_cls,
414                   GNUNET_NO);
415     return;
416   }
417
418   cc->mqm_ready = GNUNET_YES;
419   LOG (GNUNET_ERROR_TYPE_DEBUG,
420        "Core MQ for connection %s became available in state %d\n",
421        GCC_2s (cc),
422        cc->state);
423   switch (cc->state)
424   {
425   case CADET_CONNECTION_NEW:
426     /* Transmit immediately */
427     cc->task = GNUNET_SCHEDULER_add_now (&send_create,
428                                          cc);
429     break;
430   case CADET_CONNECTION_SENDING_CREATE:
431     /* Should not be possible to be called in this state. */
432     GNUNET_assert (0);
433     break;
434   case CADET_CONNECTION_SENT:
435     /* Retry a bit later... */
436     cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
437     cc->task = GNUNET_SCHEDULER_add_delayed (cc->retry_delay,
438                                              &send_create,
439                                              cc);
440     break;
441   case CADET_CONNECTION_CREATE_RECEIVED:
442     /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */
443     cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
444                                          cc);
445     break;
446   case CADET_CONNECTION_READY:
447     cc->ready_cb (cc->ready_cb_cls,
448                   GNUNET_YES);
449     break;
450   }
451 }
452
453
454 /**
455  * Create a connection to @a destination via @a path and notify @a cb
456  * whenever we are ready for more data.  Shared logic independent of
457  * who is initiating the connection.
458  *
459  * @param destination where to go
460  * @param path which path to take (may not be the full path)
461  * @param ct which tunnel uses this connection
462  * @param init_state initial state for the connection
463  * @param ready_cb function to call when ready to transmit
464  * @param ready_cb_cls closure for @a cb
465  * @return handle to the connection
466  */
467 static struct CadetConnection *
468 connection_create (struct CadetPeer *destination,
469                    struct CadetPeerPath *path,
470                    struct CadetTConnection *ct,
471                    const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
472                    enum CadetConnectionState init_state,
473                    GCC_ReadyCallback ready_cb,
474                    void *ready_cb_cls)
475 {
476   struct CadetConnection *cc;
477   struct CadetPeer *first_hop;
478   unsigned int off;
479
480   off = GCPP_find_peer (path,
481                         destination);
482   GNUNET_assert (UINT_MAX > off);
483   cc = GNUNET_new (struct CadetConnection);
484   cc->state = init_state;
485   cc->ct = ct;
486   cc->cid = *cid;
487   GNUNET_assert (GNUNET_OK ==
488                  GNUNET_CONTAINER_multishortmap_put (connections,
489                                                      &GCC_get_id (cc)->connection_of_tunnel,
490                                                      cc,
491                                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
492   cc->ready_cb = ready_cb;
493   cc->ready_cb_cls = ready_cb_cls;
494   cc->path = path;
495   cc->off = off;
496   GCPP_add_connection (path,
497                        off,
498                        cc);
499   for (unsigned int i=0;i<off;i++)
500     GCP_add_connection (GCPP_get_peer_at_offset (path,
501                                                  off),
502                         cc);
503
504   first_hop = GCPP_get_peer_at_offset (path,
505                                        0);
506   cc->mq_man = GCP_request_mq (first_hop,
507                                &manage_first_hop_mq,
508                                cc);
509   LOG (GNUNET_ERROR_TYPE_DEBUG,
510        "Created connection %s using path %s\n",
511        GCC_2s (cc),
512        GCPP_2s (path));
513   return cc;
514 }
515
516
517 /**
518  * Create a connection to @a destination via @a path and
519  * notify @a cb whenever we are ready for more data.  This
520  * is an inbound tunnel, so we must use the existing @a cid
521  *
522  * @param destination where to go
523  * @param path which path to take (may not be the full path)
524  * @param ct which tunnel uses this connection
525  * @param ready_cb function to call when ready to transmit
526  * @param ready_cb_cls closure for @a cb
527  * @return handle to the connection
528  */
529 struct CadetConnection *
530 GCC_create_inbound (struct CadetPeer *destination,
531                     struct CadetPeerPath *path,
532                     struct CadetTConnection *ct,
533                     const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
534                     GCC_ReadyCallback ready_cb,
535                     void *ready_cb_cls)
536 {
537   return connection_create (destination,
538                             path,
539                             ct,
540                             cid,
541                             CADET_CONNECTION_CREATE_RECEIVED,
542                             ready_cb,
543                             ready_cb_cls);
544 }
545
546
547 /**
548  * Create a connection to @a destination via @a path and
549  * notify @a cb whenever we are ready for more data.
550  *
551  * @param destination where to go
552  * @param path which path to take (may not be the full path)
553  * @param ct tunnel that uses the connection
554  * @param ready_cb function to call when ready to transmit
555  * @param ready_cb_cls closure for @a cb
556  * @return handle to the connection
557  */
558 struct CadetConnection *
559 GCC_create (struct CadetPeer *destination,
560             struct CadetPeerPath *path,
561             struct CadetTConnection *ct,
562             GCC_ReadyCallback ready_cb,
563             void *ready_cb_cls)
564 {
565   struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
566
567   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
568                               &cid,
569                               sizeof (cid));
570   return connection_create (destination,
571                             path,
572                             ct,
573                             &cid,
574                             CADET_CONNECTION_NEW,
575                             ready_cb,
576                             ready_cb_cls);
577 }
578
579
580 /**
581  * Transmit message @a msg via connection @a cc.  Must only be called
582  * (once) after the connection has signalled that it is ready via the
583  * `ready_cb`.  Clients can also use #GCC_is_ready() to check if the
584  * connection is right now ready for transmission.
585  *
586  * @param cc connection identification
587  * @param env envelope with message to transmit; must NOT
588  *            yet have a #GNUNET_MQ_notify_sent() callback attached to it
589  */
590 void
591 GCC_transmit (struct CadetConnection *cc,
592               struct GNUNET_MQ_Envelope *env)
593 {
594   LOG (GNUNET_ERROR_TYPE_DEBUG,
595        "Scheduling message for transmission on %s\n",
596        GCC_2s (cc));
597   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
598   GNUNET_assert (CADET_CONNECTION_READY == cc->state);
599   cc->mqm_ready = GNUNET_NO;
600   GCP_send (cc->mq_man,
601             env);
602 }
603
604
605 /**
606  * Obtain the path used by this connection.
607  *
608  * @param cc connection
609  * @return path to @a cc
610  */
611 struct CadetPeerPath *
612 GCC_get_path (struct CadetConnection *cc)
613 {
614   return cc->path;
615 }
616
617
618 /**
619  * Obtain unique ID for the connection.
620  *
621  * @param cc connection.
622  * @return unique number of the connection
623  */
624 const struct GNUNET_CADET_ConnectionTunnelIdentifier *
625 GCC_get_id (struct CadetConnection *cc)
626 {
627   return &cc->cid;
628 }
629
630
631 /**
632  * Get a (static) string for a connection.
633  *
634  * @param cc Connection.
635  */
636 const char *
637 GCC_2s (const struct CadetConnection *cc)
638 {
639   static char buf[128];
640
641   if (NULL == cc)
642     return "Connection(NULL)";
643
644   if (NULL != cc->ct)
645   {
646     GNUNET_snprintf (buf,
647                      sizeof (buf),
648                      "Connection(%s(Tunnel(%s)))",
649                      GNUNET_sh2s (&cc->cid.connection_of_tunnel),
650                      GCT_2s (cc->ct->t));
651     return buf;
652   }
653   GNUNET_snprintf (buf,
654                    sizeof (buf),
655                    "Connection(%s(Tunnel(NULL)))",
656                    GNUNET_sh2s (&cc->cid.connection_of_tunnel));
657   return buf;
658 }
659
660
661 #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-con",__VA_ARGS__)
662
663
664 /**
665  * Log connection info.
666  *
667  * @param cc connection
668  * @param level Debug level to use.
669  */
670 void
671 GCC_debug (struct CadetConnection *cc,
672            enum GNUNET_ErrorType level)
673 {
674   int do_log;
675   char *s;
676
677   do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
678                                        "cadet-con",
679                                        __FILE__, __FUNCTION__, __LINE__);
680   if (0 == do_log)
681     return;
682   if (NULL == cc)
683   {
684     LOG2 (level,
685           "Connection (NULL)\n");
686     return;
687   }
688   s = GCPP_2s (cc->path);
689   LOG2 (level,
690         "Connection %s to %s via path %s in state %d is %s\n",
691         GCC_2s (cc),
692         GCP_2s (cc->destination),
693         s,
694         cc->state,
695         (GNUNET_YES == cc->mqm_ready) ? "ready" : "busy");
696   GNUNET_free (s);
697 }
698
699 /* end of gnunet-service-cadet-new_connection.c */