towards decrypting traffic in new CADET
[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  * - congestion control
31  * - GCC_debug()
32  * - keepalive messages
33  * - performance metrics
34  * - back-off reset
35  */
36 #include "platform.h"
37 #include "gnunet-service-cadet-new_channel.h"
38 #include "gnunet-service-cadet-new_connection.h"
39 #include "gnunet-service-cadet-new_paths.h"
40 #include "gnunet-service-cadet-new_peer.h"
41 #include "gnunet-service-cadet-new_tunnels.h"
42 #include "gnunet_cadet_service.h"
43 #include "cadet_protocol.h"
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    * Connection confirmed, ready to carry traffic.
68    */
69   CADET_CONNECTION_READY,
70
71   /**
72    * Connection to be destroyed, just waiting to empty queues.
73    */
74   CADET_CONNECTION_DESTROYED,
75
76   /**
77    * Connection to be destroyed because of a distant peer, same as DESTROYED.
78    */
79   CADET_CONNECTION_BROKEN
80 };
81
82
83 /**
84  * Low-level connection to a destination.
85  */
86 struct CadetConnection
87 {
88
89   /**
90    * ID of the connection.
91    */
92   struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
93
94   /**
95    * To which peer does this connection go?
96    */
97   struct CadetPeer *destination;
98
99   /**
100    * Which tunnel is using this connection?
101    */
102   struct CadetTConnection *ct;
103
104   /**
105    * Path we are using to our destination.
106    */
107   struct CadetPeerPath *path;
108
109   /**
110    * Pending message, NULL if we are ready to transmit.
111    */
112   struct GNUNET_MQ_Envelope *env;
113
114   /**
115    * Message queue to the first hop, or NULL if we have no connection yet.
116    */
117   struct GNUNET_MQ_Handle *mq;
118
119   /**
120    * Handle for calling #GCP_request_mq_cancel() once we are finished.
121    */
122   struct GCP_MessageQueueManager *mq_man;
123
124   /**
125    * Task for connection maintenance.
126    */
127   struct GNUNET_SCHEDULER_Task *task;
128
129   /**
130    * Function to call once we are ready to transmit.
131    */
132   GNUNET_SCHEDULER_TaskCallback ready_cb;
133
134   /**
135    * Closure for @e ready_cb.
136    */
137   void *ready_cb_cls;
138
139   /**
140    * How long do we wait before we try again with a CREATE message?
141    */
142   struct GNUNET_TIME_Relative retry_delay;
143
144   /**
145    * State of the connection.
146    */
147   enum CadetConnectionState state;
148
149   /**
150    * Offset of our @e destination in @e path.
151    */
152   unsigned int off;
153
154 };
155
156
157 /**
158  * Is the given connection currently ready for transmission?
159  *
160  * @param cc connection to transmit on
161  * @return #GNUNET_YES if we could transmit
162  */
163 int
164 GCC_is_ready (struct CadetConnection *cc)
165 {
166   return ( (NULL != cc->mq) &&
167            (CADET_CONNECTION_READY == cc->state) &&
168            (NULL == cc->env) ) ? GNUNET_YES : GNUNET_NO;
169 }
170
171
172 /**
173  * Destroy a connection.
174  *
175  * @param cc connection to destroy
176  */
177 void
178 GCC_destroy (struct CadetConnection *cc)
179 {
180   if (NULL != cc->env)
181   {
182     if (NULL != cc->mq)
183       GNUNET_MQ_send_cancel (cc->env);
184     else
185       GNUNET_MQ_discard (cc->env);
186     cc->env = NULL;
187   }
188   if ( (NULL != cc->mq) &&
189        (CADET_CONNECTION_SENDING_CREATE != cc->state) )
190   {
191     /* Need to notify next hop that we are down. */
192     struct GNUNET_MQ_Envelope *env;
193     struct GNUNET_CADET_ConnectionDestroy *destroy_msg;
194
195     env = GNUNET_MQ_msg (destroy_msg,
196                          GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY);
197     destroy_msg->cid = cc->cid;
198     GNUNET_MQ_send (cc->mq,
199                     env);
200   }
201   cc->mq = NULL;
202   GCP_request_mq_cancel (cc->mq_man);
203   cc->mq_man = NULL;
204   GCPP_del_connection (cc->path,
205                        cc->off,
206                        cc);
207   GNUNET_assert (GNUNET_YES ==
208                  GNUNET_CONTAINER_multishortmap_remove (connections,
209                                                         &GCC_get_id (cc)->connection_of_tunnel,
210                                                         cc));
211   GNUNET_free (cc);
212 }
213
214
215 /**
216  * Return the tunnel associated with this connection.
217  *
218  * @param cc connection to query
219  * @return corresponding entry in the tunnel's connection list
220  */
221 struct CadetTConnection *
222 GCC_get_ct (struct CadetConnection *cc)
223 {
224   return cc->ct;
225 }
226
227
228 /**
229  * A connection ACK was received for this connection, implying
230  * that the end-to-end connection is up.  Process it.
231  *
232  * @param cc the connection that got the ACK.
233  */
234 void
235 GCC_handle_connection_ack (struct CadetConnection *cc)
236 {
237   GNUNET_SCHEDULER_cancel (cc->task);
238 #if FIXME
239   cc->task = GNUNET_SCHEDULER_add_delayed (cc->keepalive_period,
240                                            &send_keepalive,
241                                            cc);
242 #endif
243   cc->state = CADET_CONNECTION_READY;
244   cc->ready_cb (cc->ready_cb_cls);
245 }
246
247
248 /**
249  * Handle KX message.
250  *
251  * @param cc connection that received encrypted message
252  * @param msg the key exchange message
253  */
254 void
255 GCC_handle_kx (struct CadetConnection *cc,
256                const struct GNUNET_CADET_KX *msg)
257 {
258   GCT_handle_kx (cc->ct,
259                  msg);
260 }
261
262
263 /**
264  * Handle encrypted message.
265  *
266  * @param cc connection that received encrypted message
267  * @param msg the encrypted message to decrypt
268  */
269 void
270 GCC_handle_encrypted (struct CadetConnection *cc,
271                       const struct GNUNET_CADET_Encrypted *msg)
272 {
273   GCT_handle_encrypted (cc->ct,
274                         msg);
275 }
276
277
278 /**
279  * Send a CREATE message to the first hop.
280  *
281  * @param cls the `struct CadetConnection` to initiate
282  */
283 static void
284 send_create (void *cls);
285
286
287 /**
288  * We finished transmission of the create message, now wait for
289  * ACK or retransmit.
290  *
291  * @param cls the `struct CadetConnection` that sent the create message
292  */
293 static void
294 transmit_create_done_cb (void *cls)
295 {
296   struct CadetConnection *cc = cls;
297
298   cc->state = CADET_CONNECTION_SENT;
299   cc->env = NULL;
300   /* FIXME: at some point, we need to reset the delay back to 0! */
301   cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
302   cc->task = GNUNET_SCHEDULER_add_delayed (cc->retry_delay,
303                                            &send_create,
304                                            cc);
305 }
306
307
308 /**
309  * Send a CREATE message to the first hop.
310  *
311  * @param cls the `struct CadetConnection` to initiate
312  */
313 static void
314 send_create (void *cls)
315 {
316   struct CadetConnection *cc = cls;
317   struct GNUNET_CADET_ConnectionCreate *create_msg;
318   struct GNUNET_PeerIdentity *pids;
319   struct GNUNET_MQ_Envelope *env;
320   unsigned int path_length;
321
322   cc->task = NULL;
323   GNUNET_assert (NULL != cc->mq);
324   path_length = GCPP_get_length (cc->path);
325   env = GNUNET_MQ_msg_extra (create_msg,
326                              path_length * sizeof (struct GNUNET_PeerIdentity),
327                              GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
328   create_msg->cid = cc->cid;
329   pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
330   for (unsigned int i=0;i<path_length;i++)
331     pids[i] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
332                                                     i));
333   cc->env = env;
334   GNUNET_MQ_notify_sent (env,
335                          &transmit_create_done_cb,
336                          cc);
337   GNUNET_MQ_send (cc->mq,
338                   env);
339 }
340
341
342 /**
343  * There has been a change in the message queue existence for our
344  * peer at the first hop.  Adjust accordingly.
345  *
346  * @param cls the `struct CadetConnection`
347  * @param mq NULL if the CORE connection was lost, non-NULL if
348  *           it became available
349  */
350 static void
351 manage_first_hop_mq (void *cls,
352                      struct GNUNET_MQ_Handle *mq)
353 {
354   struct CadetConnection *cc = cls;
355
356   if (NULL == mq)
357   {
358     /* Connection is down, for now... */
359     cc->mq = NULL;
360     if (NULL != cc->task)
361     {
362       GNUNET_SCHEDULER_cancel (cc->task);
363       cc->task = NULL;
364     }
365     return;
366   }
367
368   cc->mq = mq;
369   cc->state = CADET_CONNECTION_SENDING_CREATE;
370
371   /* Now repeat sending connection creation messages
372      down the path, until we get an ACK! */
373   cc->task = GNUNET_SCHEDULER_add_now (&send_create,
374                                        cc);
375 }
376
377
378 /**
379  * Create a connection to @a destination via @a path and
380  * notify @a cb whenever we are ready for more data.
381  *
382  * @param destination where to go
383  * @param path which path to take (may not be the full path)
384  * @param ct tunnel that uses the connection
385  * @param ready_cb function to call when ready to transmit
386  * @param ready_cb_cls closure for @a cb
387  * @return handle to the connection
388  */
389 struct CadetConnection *
390 GCC_create (struct CadetPeer *destination,
391             struct CadetPeerPath *path,
392             struct CadetTConnection *ct,
393             GNUNET_SCHEDULER_TaskCallback ready_cb,
394             void *ready_cb_cls)
395 {
396   struct CadetConnection *cc;
397   struct CadetPeer *first_hop;
398   unsigned int off;
399
400   off = GCPP_find_peer (path,
401                         destination);
402   GNUNET_assert (UINT_MAX > off);
403   cc = GNUNET_new (struct CadetConnection);
404   cc->ct = ct;
405   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
406                               &cc->cid,
407                               sizeof (cc->cid));
408   GNUNET_assert (GNUNET_OK ==
409                  GNUNET_CONTAINER_multishortmap_put (connections,
410                                                      &GCC_get_id (cc)->connection_of_tunnel,
411                                                      cc,
412                                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
413   cc->ready_cb = ready_cb;
414   cc->ready_cb_cls = ready_cb_cls;
415   cc->path = path;
416   cc->off = off;
417   GCPP_add_connection (path,
418                        off,
419                        cc);
420   for (unsigned int i=0;i<off;i++)
421     GCP_add_connection (GCPP_get_peer_at_offset (path,
422                                                  off),
423                         cc);
424
425   first_hop = GCPP_get_peer_at_offset (path,
426                                        0);
427   cc->mq_man = GCP_request_mq (first_hop,
428                                &manage_first_hop_mq,
429                                cc);
430   return cc;
431 }
432
433
434 /**
435  * We finished transmission of a message, if we are still ready, tell
436  * the tunnel!
437  *
438  * @param cls our `struct CadetConnection`
439  */
440 static void
441 transmit_done_cb (void *cls)
442 {
443   struct CadetConnection *cc = cls;
444
445   cc->env = NULL;
446   if ( (NULL != cc->mq) &&
447        (CADET_CONNECTION_READY == cc->state) )
448     cc->ready_cb (cc->ready_cb_cls);
449 }
450
451
452 /**
453  * Transmit message @a msg via connection @a cc.  Must only be called
454  * (once) after the connection has signalled that it is ready via the
455  * `ready_cb`.  Clients can also use #GCC_is_ready() to check if the
456  * connection is right now ready for transmission.
457  *
458  * @param cc connection identification
459  * @param env envelope with message to transmit
460  */
461 void
462 GCC_transmit (struct CadetConnection *cc,
463               struct GNUNET_MQ_Envelope *env)
464 {
465   GNUNET_assert (NULL == cc->env);
466   cc->env = env;
467   GNUNET_MQ_notify_sent (env,
468                          &transmit_done_cb,
469                          cc);
470   if ( (NULL != cc->mq) &&
471        (CADET_CONNECTION_READY == cc->state) )
472     GNUNET_MQ_send (cc->mq,
473                     env);
474 }
475
476
477 /**
478  * Obtain the path used by this connection.
479  *
480  * @param cc connection
481  * @return path to @a cc
482  */
483 struct CadetPeerPath *
484 GCC_get_path (struct CadetConnection *cc)
485 {
486   return cc->path;
487 }
488
489
490 /**
491  * Obtain unique ID for the connection.
492  *
493  * @param cc connection.
494  * @return unique number of the connection
495  */
496 const struct GNUNET_CADET_ConnectionTunnelIdentifier *
497 GCC_get_id (struct CadetConnection *cc)
498 {
499   return &cc->cid;
500 }
501
502
503 /**
504  * Log connection info.
505  *
506  * @param cc connection
507  * @param level Debug level to use.
508  */
509 void
510 GCC_debug (struct CadetConnection *cc,
511            enum GNUNET_ErrorType level)
512 {
513   GNUNET_break (0); // FIXME: implement...
514 }
515
516 /* end of gnunet-service-cadet-new_connection.c */