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