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