more LOG macros
[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);
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   for (unsigned int i=0;i<path_length;i++)
304     pids[i] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
305                                                     i));
306   LOG (GNUNET_ERROR_TYPE_DEBUG,
307        "Sending CONNECTION_CREATE message for connection %s\n",
308        GCC_2s (cc));
309   cc->env = env;
310   cc->mqm_ready = GNUNET_NO;
311   cc->state = CADET_CONNECTION_SENT;
312   GCP_send (cc->mq_man,
313             env);
314 }
315
316
317 /**
318  * Send a CREATE_ACK message towards the origin.
319  *
320  * @param cls the `struct CadetConnection` to initiate
321  */
322 static void
323 send_create_ack (void *cls)
324 {
325   struct CadetConnection *cc = cls;
326   struct GNUNET_CADET_ConnectionCreateAckMessage *ack_msg;
327   struct GNUNET_MQ_Envelope *env;
328
329   cc->task = NULL;
330   LOG (GNUNET_ERROR_TYPE_DEBUG,
331        "Sending CONNECTION_CREATE_ACK message for connection %s\n",
332        GCC_2s (cc));
333   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
334   env = GNUNET_MQ_msg (ack_msg,
335                        GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK);
336   ack_msg->cid = cc->cid;
337   cc->env = env;
338   cc->mqm_ready = GNUNET_NO;
339   cc->state = CADET_CONNECTION_READY;
340   GCP_send (cc->mq_man,
341             env);
342 }
343
344
345 /**
346  * We got a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a
347  * connection that we already have.  Either our ACK got lost
348  * or something is fishy.  Consider retransmitting the ACK.
349  *
350  * @param cc connection that got the duplicate CREATE
351  */
352 void
353 GCC_handle_duplicate_create (struct CadetConnection *cc)
354 {
355   if (GNUNET_YES == cc->mqm_ready)
356   {
357     LOG (GNUNET_ERROR_TYPE_DEBUG,
358          "Got duplicate CREATE for connection %s, scheduling another ACK\n",
359          GCC_2s (cc));
360     /* Tell tunnel that we are not ready for transmission anymore
361        (until CREATE_ACK is done) */
362     cc->ready_cb (cc->ready_cb_cls,
363                   GNUNET_NO);
364     /* Revert back to the state of having only received the 'CREATE',
365        and immediately proceed to send the CREATE_ACK. */
366     cc->state = CADET_CONNECTION_CREATE_RECEIVED;
367     cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
368                                          cc);
369   }
370   else
371   {
372     /* We are currently sending something else back, which
373        can only be an ACK or payload, either of which would
374        do. So actually no need to do anything. */
375     LOG (GNUNET_ERROR_TYPE_DEBUG,
376          "Got duplicate CREATE for connection %s. MQ is busy, not queueing another ACK\n",
377          GCC_2s (cc));
378   }
379 }
380
381
382 /**
383  * There has been a change in the message queue existence for our
384  * peer at the first hop.  Adjust accordingly.
385  *
386  * @param cls the `struct CadetConnection`
387  * @param available #GNUNET_YES if sending is now possible,
388  *                  #GNUNET_NO if sending is no longer possible
389  *                  #GNUNET_SYSERR if sending is no longer possible
390  *                                 and the last envelope was discarded
391  */
392 static void
393 manage_first_hop_mq (void *cls,
394                      int available)
395 {
396   struct CadetConnection *cc = cls;
397
398   if (GNUNET_YES != available)
399   {
400     /* Connection is down, for now... */
401     LOG (GNUNET_ERROR_TYPE_DEBUG,
402          "Core MQ for connection %s went down\n",
403          GCC_2s (cc));
404     cc->mqm_ready = GNUNET_NO;
405     cc->state = CADET_CONNECTION_NEW;
406     cc->retry_delay = GNUNET_TIME_UNIT_ZERO;
407     if (NULL != cc->task)
408     {
409       GNUNET_SCHEDULER_cancel (cc->task);
410       cc->task = NULL;
411     }
412     cc->ready_cb (cc->ready_cb_cls,
413                   GNUNET_NO);
414     return;
415   }
416
417   cc->mqm_ready = GNUNET_YES;
418   LOG (GNUNET_ERROR_TYPE_DEBUG,
419        "Core MQ for connection %s became available in state %d\n",
420        GCC_2s (cc),
421        cc->state);
422   switch (cc->state)
423   {
424   case CADET_CONNECTION_NEW:
425     /* Transmit immediately */
426     cc->task = GNUNET_SCHEDULER_add_now (&send_create,
427                                          cc);
428     break;
429   case CADET_CONNECTION_SENDING_CREATE:
430     /* Should not be possible to be called in this state. */
431     GNUNET_assert (0);
432     break;
433   case CADET_CONNECTION_SENT:
434     /* Retry a bit later... */
435     cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
436     cc->task = GNUNET_SCHEDULER_add_delayed (cc->retry_delay,
437                                              &send_create,
438                                              cc);
439     break;
440   case CADET_CONNECTION_CREATE_RECEIVED:
441     /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */
442     cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
443                                          cc);
444     break;
445   case CADET_CONNECTION_READY:
446     cc->ready_cb (cc->ready_cb_cls,
447                   GNUNET_YES);
448     break;
449   }
450 }
451
452
453 /**
454  * Create a connection to @a destination via @a path and notify @a cb
455  * whenever we are ready for more data.  Shared logic independent of
456  * who is initiating the connection.
457  *
458  * @param destination where to go
459  * @param path which path to take (may not be the full path)
460  * @param ct which tunnel uses this connection
461  * @param init_state initial state for the connection
462  * @param ready_cb function to call when ready to transmit
463  * @param ready_cb_cls closure for @a cb
464  * @return handle to the connection
465  */
466 static struct CadetConnection *
467 connection_create (struct CadetPeer *destination,
468                    struct CadetPeerPath *path,
469                    struct CadetTConnection *ct,
470                    const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
471                    enum CadetConnectionState init_state,
472                    GCC_ReadyCallback ready_cb,
473                    void *ready_cb_cls)
474 {
475   struct CadetConnection *cc;
476   struct CadetPeer *first_hop;
477   unsigned int off;
478
479   off = GCPP_find_peer (path,
480                         destination);
481   GNUNET_assert (UINT_MAX > off);
482   cc = GNUNET_new (struct CadetConnection);
483   cc->state = init_state;
484   cc->ct = ct;
485   cc->cid = *cid;
486   GNUNET_assert (GNUNET_OK ==
487                  GNUNET_CONTAINER_multishortmap_put (connections,
488                                                      &GCC_get_id (cc)->connection_of_tunnel,
489                                                      cc,
490                                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
491   cc->ready_cb = ready_cb;
492   cc->ready_cb_cls = ready_cb_cls;
493   cc->path = path;
494   cc->off = off;
495   GCPP_add_connection (path,
496                        off,
497                        cc);
498   for (unsigned int i=0;i<off;i++)
499     GCP_add_connection (GCPP_get_peer_at_offset (path,
500                                                  off),
501                         cc);
502
503   first_hop = GCPP_get_peer_at_offset (path,
504                                        0);
505   cc->mq_man = GCP_request_mq (first_hop,
506                                &manage_first_hop_mq,
507                                cc);
508   LOG (GNUNET_ERROR_TYPE_DEBUG,
509        "Created connection %s using path %s\n",
510        GCC_2s (cc),
511        GCPP_2s (path));
512   return cc;
513 }
514
515
516 /**
517  * Create a connection to @a destination via @a path and
518  * notify @a cb whenever we are ready for more data.  This
519  * is an inbound tunnel, so we must use the existing @a cid
520  *
521  * @param destination where to go
522  * @param path which path to take (may not be the full path)
523  * @param ct which tunnel uses this connection
524  * @param ready_cb function to call when ready to transmit
525  * @param ready_cb_cls closure for @a cb
526  * @return handle to the connection
527  */
528 struct CadetConnection *
529 GCC_create_inbound (struct CadetPeer *destination,
530                     struct CadetPeerPath *path,
531                     struct CadetTConnection *ct,
532                     const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
533                     GCC_ReadyCallback ready_cb,
534                     void *ready_cb_cls)
535 {
536   return connection_create (destination,
537                             path,
538                             ct,
539                             cid,
540                             CADET_CONNECTION_CREATE_RECEIVED,
541                             ready_cb,
542                             ready_cb_cls);
543 }
544
545
546 /**
547  * Create a connection to @a destination via @a path and
548  * notify @a cb whenever we are ready for more data.
549  *
550  * @param destination where to go
551  * @param path which path to take (may not be the full path)
552  * @param ct tunnel that uses the connection
553  * @param ready_cb function to call when ready to transmit
554  * @param ready_cb_cls closure for @a cb
555  * @return handle to the connection
556  */
557 struct CadetConnection *
558 GCC_create (struct CadetPeer *destination,
559             struct CadetPeerPath *path,
560             struct CadetTConnection *ct,
561             GCC_ReadyCallback ready_cb,
562             void *ready_cb_cls)
563 {
564   struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
565
566   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
567                               &cid,
568                               sizeof (cid));
569   return connection_create (destination,
570                             path,
571                             ct,
572                             &cid,
573                             CADET_CONNECTION_NEW,
574                             ready_cb,
575                             ready_cb_cls);
576 }
577
578
579 /**
580  * Transmit message @a msg via connection @a cc.  Must only be called
581  * (once) after the connection has signalled that it is ready via the
582  * `ready_cb`.  Clients can also use #GCC_is_ready() to check if the
583  * connection is right now ready for transmission.
584  *
585  * @param cc connection identification
586  * @param env envelope with message to transmit; must NOT
587  *            yet have a #GNUNET_MQ_notify_sent() callback attached to it
588  */
589 void
590 GCC_transmit (struct CadetConnection *cc,
591               struct GNUNET_MQ_Envelope *env)
592 {
593   LOG (GNUNET_ERROR_TYPE_DEBUG,
594        "Scheduling message for transmission on %s\n",
595        GCC_2s (cc));
596   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
597   GNUNET_assert (CADET_CONNECTION_READY == cc->state);
598   cc->mqm_ready = GNUNET_NO;
599   GCP_send (cc->mq_man,
600             env);
601 }
602
603
604 /**
605  * Obtain the path used by this connection.
606  *
607  * @param cc connection
608  * @return path to @a cc
609  */
610 struct CadetPeerPath *
611 GCC_get_path (struct CadetConnection *cc)
612 {
613   return cc->path;
614 }
615
616
617 /**
618  * Obtain unique ID for the connection.
619  *
620  * @param cc connection.
621  * @return unique number of the connection
622  */
623 const struct GNUNET_CADET_ConnectionTunnelIdentifier *
624 GCC_get_id (struct CadetConnection *cc)
625 {
626   return &cc->cid;
627 }
628
629
630 /**
631  * Get a (static) string for a connection.
632  *
633  * @param cc Connection.
634  */
635 const char *
636 GCC_2s (const struct CadetConnection *cc)
637 {
638   static char buf[128];
639
640   if (NULL == cc)
641     return "Connection(NULL)";
642
643   if (NULL != cc->ct)
644   {
645     GNUNET_snprintf (buf,
646                      sizeof (buf),
647                      "Connection(%s(Tunnel(%s)))",
648                      GNUNET_sh2s (&cc->cid.connection_of_tunnel),
649                      GCT_2s (cc->ct->t));
650     return buf;
651   }
652   GNUNET_snprintf (buf,
653                    sizeof (buf),
654                    "Connection(%s(Tunnel(NULL)))",
655                    GNUNET_sh2s (&cc->cid.connection_of_tunnel));
656   return buf;
657 }
658
659
660 #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-con",__VA_ARGS__)
661
662
663 /**
664  * Log connection info.
665  *
666  * @param cc connection
667  * @param level Debug level to use.
668  */
669 void
670 GCC_debug (struct CadetConnection *cc,
671            enum GNUNET_ErrorType level)
672 {
673   int do_log;
674   char *s;
675
676   do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
677                                        "cadet-con",
678                                        __FILE__, __FUNCTION__, __LINE__);
679   if (0 == do_log)
680     return;
681   if (NULL == cc)
682   {
683     LOG2 (level,
684           "Connection (NULL)\n");
685     return;
686   }
687   s = GCPP_2s (cc->path);
688   LOG2 (level,
689         "Connection %s to %s via path %s in state %d is %s\n",
690         GCC_2s (cc),
691         GCP_2s (cc->destination),
692         s,
693         cc->state,
694         (GNUNET_YES == cc->mqm_ready) ? "ready" : "busy");
695   GNUNET_free (s);
696 }
697
698 /* end of gnunet-service-cadet-new_connection.c */