Merge branch 'schanzen/argon_pow'
[oweals/gnunet.git] / src / cadet / gnunet-service-cadet.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2001-2013, 2017 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21 /**
22  * @file cadet/gnunet-service-cadet.c
23  * @brief GNUnet CADET service with encryption
24  * @author Bartlomiej Polot
25  * @author Christian Grothoff
26  *
27  * Dictionary:
28  * - peer: other cadet instance. If there is direct connection it's a neighbor.
29  * - path: series of directly connected peer from one peer to another.
30  * - connection: path which is being used in a tunnel.
31  * - tunnel: encrypted connection to a peer, neighbor or not.
32  * - channel: logical link between two clients, on the same or different peers.
33  *            have properties like reliability.
34  */
35 #include "platform.h"
36 #include "gnunet_util_lib.h"
37 #include "cadet.h"
38 #include "gnunet_statistics_service.h"
39 #include "gnunet-service-cadet.h"
40 #include "gnunet-service-cadet_channel.h"
41 #include "gnunet-service-cadet_connection.h"
42 #include "gnunet-service-cadet_core.h"
43 #include "gnunet-service-cadet_dht.h"
44 #include "gnunet-service-cadet_hello.h"
45 #include "gnunet-service-cadet_tunnels.h"
46 #include "gnunet-service-cadet_peer.h"
47 #include "gnunet-service-cadet_paths.h"
48
49 #define LOG(level, ...) GNUNET_log (level, __VA_ARGS__)
50
51
52 /**
53  * Struct containing information about a client of the service
54  */
55 struct CadetClient
56 {
57   /**
58    * Linked list next
59    */
60   struct CadetClient *next;
61
62   /**
63    * Linked list prev
64    */
65   struct CadetClient *prev;
66
67   /**
68    * Tunnels that belong to this client, indexed by local id,
69    * value is a `struct CadetChannel`.
70    */
71   struct GNUNET_CONTAINER_MultiHashMap32 *channels;
72
73   /**
74    * Handle to communicate with the client
75    */
76   struct GNUNET_MQ_Handle *mq;
77
78   /**
79    * Client handle.
80    */
81   struct GNUNET_SERVICE_Client *client;
82
83   /**
84    * Ports that this client has declared interest in.
85    * Indexed by port, contains `struct OpenPort`
86    */
87   struct GNUNET_CONTAINER_MultiHashMap *ports;
88
89   /**
90    * Channel ID to use for the next incoming channel for this client.
91    * Wraps around (in theory).
92    */
93   struct GNUNET_CADET_ClientChannelNumber next_ccn;
94
95   /**
96    * ID of the client, mainly for debug messages. Purely internal to this file.
97    */
98   unsigned int id;
99 };
100
101
102 /******************************************************************************/
103 /***********************      GLOBAL VARIABLES     ****************************/
104 /******************************************************************************/
105
106 /****************************** Global variables ******************************/
107
108 /**
109  * Handle to our configuration.
110  */
111 const struct GNUNET_CONFIGURATION_Handle *cfg;
112
113 /**
114  * Handle to the statistics service.
115  */
116 struct GNUNET_STATISTICS_Handle *stats;
117
118 /**
119  * Handle to communicate with ATS.
120  */
121 struct GNUNET_ATS_ConnectivityHandle *ats_ch;
122
123 /**
124  * Local peer own ID.
125  */
126 struct GNUNET_PeerIdentity my_full_id;
127
128 /**
129  * Own private key.
130  */
131 struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
132
133 /**
134  * Signal that shutdown is happening: prevent recovery measures.
135  */
136 int shutting_down;
137
138 /**
139  * DLL with all the clients, head.
140  */
141 static struct CadetClient *clients_head;
142
143 /**
144  * DLL with all the clients, tail.
145  */
146 static struct CadetClient *clients_tail;
147
148 /**
149  * Next ID to assign to a client.
150  */
151 static unsigned int next_client_id;
152
153 /**
154  * All ports clients of this peer have opened.  Maps from
155  * a hashed port to a `struct OpenPort`.
156  */
157 struct GNUNET_CONTAINER_MultiHashMap *open_ports;
158
159 /**
160  * Map from ports to channels where the ports were closed at the
161  * time we got the inbound connection.
162  * Indexed by h_port, contains `struct CadetChannel`.
163  */
164 struct GNUNET_CONTAINER_MultiHashMap *loose_channels;
165
166 /**
167  * Map from PIDs to `struct CadetPeer` entries.
168  */
169 struct GNUNET_CONTAINER_MultiPeerMap *peers;
170
171 /**
172  * Map from `struct GNUNET_CADET_ConnectionTunnelIdentifier`
173  * hash codes to `struct CadetConnection` objects.
174  */
175 struct GNUNET_CONTAINER_MultiShortmap *connections;
176
177 /**
178  * How many messages are needed to trigger an AXOLOTL ratchet advance.
179  */
180 unsigned long long ratchet_messages;
181
182 /**
183  * How long until we trigger a ratched advance due to time.
184  */
185 struct GNUNET_TIME_Relative ratchet_time;
186
187 /**
188  * How frequently do we send KEEPALIVE messages on idle connections?
189  */
190 struct GNUNET_TIME_Relative keepalive_period;
191
192 /**
193  * Set to non-zero values to create random drops to test retransmissions.
194  */
195 unsigned long long drop_percent;
196
197
198 /**
199  * Send a message to a client.
200  *
201  * @param c client to get the message
202  * @param env envelope with the message
203  */
204 void
205 GSC_send_to_client (struct CadetClient *c,
206                     struct GNUNET_MQ_Envelope *env)
207 {
208   GNUNET_MQ_send (c->mq,
209                   env);
210 }
211
212
213 /**
214  * Return identifier for a client as a string.
215  *
216  * @param c client to identify
217  * @return string for debugging
218  */
219 const char *
220 GSC_2s (struct CadetClient *c)
221 {
222   static char buf[32];
223
224   GNUNET_snprintf (buf,
225                    sizeof(buf),
226                    "Client(%u)",
227                    c->id);
228   return buf;
229 }
230
231
232 /**
233  * Lookup channel of client @a c by @a ccn.
234  *
235  * @param c client to look in
236  * @param ccn channel ID to look up
237  * @return NULL if no such channel exists
238  */
239 static struct CadetChannel *
240 lookup_channel (struct CadetClient *c,
241                 struct GNUNET_CADET_ClientChannelNumber ccn)
242 {
243   return GNUNET_CONTAINER_multihashmap32_get (c->channels,
244                                               ntohl (ccn.channel_of_client));
245 }
246
247
248 /**
249  * Obtain the next LID to use for incoming connections to
250  * the given client.
251  *
252  * @param c client handle
253  */
254 static struct GNUNET_CADET_ClientChannelNumber
255 client_get_next_ccn (struct CadetClient *c)
256 {
257   struct GNUNET_CADET_ClientChannelNumber ccn = c->next_ccn;
258
259   /* increment until we have a free one... */
260   while (NULL !=
261          lookup_channel (c,
262                          ccn))
263   {
264     ccn.channel_of_client
265       = htonl (1 + (ntohl (ccn.channel_of_client)));
266     if (ntohl (ccn.channel_of_client) >=
267         GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
268       ccn.channel_of_client = htonl (0);
269   }
270   c->next_ccn.channel_of_client
271     = htonl (1 + (ntohl (ccn.channel_of_client)));
272   return ccn;
273 }
274
275
276 /**
277  * Bind incoming channel to this client, and notify client about
278  * incoming connection.  Caller is responsible for notifying the other
279  * peer about our acceptance of the channel.
280  *
281  * @param c client to bind to
282  * @param ch channel to be bound
283  * @param dest peer that establishes the connection
284  * @param port port number
285  * @param options options
286  * @return local channel number assigned to the new client
287  */
288 struct GNUNET_CADET_ClientChannelNumber
289 GSC_bind (struct CadetClient *c,
290           struct CadetChannel *ch,
291           struct CadetPeer *dest,
292           const struct GNUNET_HashCode *port,
293           uint32_t options)
294 {
295   struct GNUNET_MQ_Envelope *env;
296   struct GNUNET_CADET_LocalChannelCreateMessage *cm;
297   struct GNUNET_CADET_ClientChannelNumber ccn;
298
299   ccn = client_get_next_ccn (c);
300   GNUNET_assert (GNUNET_YES ==
301                  GNUNET_CONTAINER_multihashmap32_put (c->channels,
302                                                       ntohl (
303                                                         ccn.channel_of_client),
304                                                       ch,
305                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
306   LOG (GNUNET_ERROR_TYPE_DEBUG,
307        "Accepting incoming %s from %s on open port %s (%u), assigning ccn %X\n",
308        GCCH_2s (ch),
309        GCP_2s (dest),
310        GNUNET_h2s (port),
311        (uint32_t) ntohl (options),
312        (uint32_t) ntohl (ccn.channel_of_client));
313   /* notify local client about incoming connection! */
314   env = GNUNET_MQ_msg (cm,
315                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
316   cm->ccn = ccn;
317   cm->port = *port;
318   cm->opt = htonl (options);
319   cm->peer = *GCP_get_id (dest);
320   GSC_send_to_client (c,
321                       env);
322   return ccn;
323 }
324
325
326 /**
327  * Callback invoked on all peers to destroy all tunnels
328  * that may still exist.
329  *
330  * @param cls NULL
331  * @param pid identify of a peer
332  * @param value a `struct CadetPeer` that may still have a tunnel
333  * @return #GNUNET_OK (iterate over all entries)
334  */
335 static int
336 destroy_tunnels_now (void *cls,
337                      const struct GNUNET_PeerIdentity *pid,
338                      void *value)
339 {
340   struct CadetPeer *cp = value;
341   struct CadetTunnel *t = GCP_get_tunnel (cp,
342                                           GNUNET_NO);
343
344   if (NULL != t)
345     GCT_destroy_tunnel_now (t);
346   return GNUNET_OK;
347 }
348
349
350 /**
351  * Callback invoked on all peers to destroy all tunnels
352  * that may still exist.
353  *
354  * @param cls NULL
355  * @param pid identify of a peer
356  * @param value a `struct CadetPeer` that may still have a tunnel
357  * @return #GNUNET_OK (iterate over all entries)
358  */
359 static int
360 destroy_paths_now (void *cls,
361                    const struct GNUNET_PeerIdentity *pid,
362                    void *value)
363 {
364   struct CadetPeer *cp = value;
365
366   GCP_drop_owned_paths (cp);
367   return GNUNET_OK;
368 }
369
370
371 /**
372  * Shutdown everything once the clients have disconnected.
373  */
374 static void
375 shutdown_rest ()
376 {
377   if (NULL != stats)
378   {
379     GNUNET_STATISTICS_destroy (stats,
380                                GNUNET_NO);
381     stats = NULL;
382   }
383   /* Destroy tunnels.  Note that all channels must be destroyed first! */
384   GCP_iterate_all (&destroy_tunnels_now,
385                    NULL);
386   /* All tunnels, channels, connections and CORE must be down before this point. */
387   GCP_iterate_all (&destroy_paths_now,
388                    NULL);
389   /* All paths, tunnels, channels, connections and CORE must be down before this point. */
390   GCP_destroy_all_peers ();
391   if (NULL != open_ports)
392   {
393     GNUNET_CONTAINER_multihashmap_destroy (open_ports);
394     open_ports = NULL;
395   }
396   if (NULL != loose_channels)
397   {
398     GNUNET_CONTAINER_multihashmap_destroy (loose_channels);
399     loose_channels = NULL;
400   }
401   if (NULL != peers)
402   {
403     GNUNET_CONTAINER_multipeermap_destroy (peers);
404     peers = NULL;
405   }
406   if (NULL != connections)
407   {
408     GNUNET_CONTAINER_multishortmap_destroy (connections);
409     connections = NULL;
410   }
411   if (NULL != ats_ch)
412   {
413     GNUNET_ATS_connectivity_done (ats_ch);
414     ats_ch = NULL;
415   }
416   GCD_shutdown ();
417   GCH_shutdown ();
418   GNUNET_free_non_null (my_private_key);
419   my_private_key = NULL;
420 }
421
422
423 /**
424  * Task run during shutdown.
425  *
426  * @param cls unused
427  */
428 static void
429 shutdown_task (void *cls)
430 {
431   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
432               "Shutting down\n");
433   shutting_down = GNUNET_YES;
434   GCO_shutdown ();
435   if (NULL == clients_head)
436     shutdown_rest ();
437 }
438
439
440 /**
441  * We had a remote connection @a value to port @a h_port before
442  * client @a cls opened port @a port.  Bind them now.
443  *
444  * @param cls the `struct CadetClient`
445  * @param h_port the hashed port
446  * @param value the `struct CadetChannel`
447  * @return #GNUNET_YES (iterate over all such channels)
448  */
449 static int
450 bind_loose_channel (void *cls,
451                     const struct GNUNET_HashCode *port,
452                     void *value)
453 {
454   struct OpenPort *op = cls;
455   struct CadetChannel *ch = value;
456
457   GCCH_bind (ch,
458              op->c,
459              &op->port);
460   GNUNET_assert (GNUNET_YES ==
461                  GNUNET_CONTAINER_multihashmap_remove (loose_channels,
462                                                        &op->h_port,
463                                                        ch));
464   return GNUNET_YES;
465 }
466
467
468 /**
469  * Handle port open request.  Creates a mapping from the
470  * port to the respective client and checks whether we have
471  * loose channels trying to bind to the port.  If so, those
472  * are bound.
473  *
474  * @param cls Identification of the client.
475  * @param pmsg The actual message.
476  */
477 static void
478 handle_port_open (void *cls,
479                   const struct GNUNET_CADET_PortMessage *pmsg)
480 {
481   struct CadetClient *c = cls;
482   struct OpenPort *op;
483
484   LOG (GNUNET_ERROR_TYPE_DEBUG,
485        "Open port %s requested by %s\n",
486        GNUNET_h2s (&pmsg->port),
487        GSC_2s (c));
488   if (NULL == c->ports)
489     c->ports = GNUNET_CONTAINER_multihashmap_create (4,
490                                                      GNUNET_NO);
491   op = GNUNET_new (struct OpenPort);
492   op->c = c;
493   op->port = pmsg->port;
494   GCCH_hash_port (&op->h_port,
495                   &pmsg->port,
496                   &my_full_id);
497   if (GNUNET_OK !=
498       GNUNET_CONTAINER_multihashmap_put (c->ports,
499                                          &op->port,
500                                          op,
501                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
502   {
503     GNUNET_break (0);
504     GNUNET_SERVICE_client_drop (c->client);
505     return;
506   }
507   (void) GNUNET_CONTAINER_multihashmap_put (open_ports,
508                                             &op->h_port,
509                                             op,
510                                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
511   GNUNET_CONTAINER_multihashmap_get_multiple (loose_channels,
512                                               &op->h_port,
513                                               &bind_loose_channel,
514                                               op);
515   GNUNET_SERVICE_client_continue (c->client);
516 }
517
518
519 /**
520  * Handler for port close requests.  Marks this port as closed
521  * (unless of course we have another client with the same port
522  * open).  Note that existing channels accepted on the port are
523  * not affected.
524  *
525  * @param cls Identification of the client.
526  * @param pmsg The actual message.
527  */
528 static void
529 handle_port_close (void *cls,
530                    const struct GNUNET_CADET_PortMessage *pmsg)
531 {
532   struct CadetClient *c = cls;
533   struct OpenPort *op;
534
535   LOG (GNUNET_ERROR_TYPE_DEBUG,
536        "Closing port %s as requested by %s\n",
537        GNUNET_h2s (&pmsg->port),
538        GSC_2s (c));
539   if (NULL == c->ports)
540   {
541     /* Client closed a port despite _never_ having opened one? */
542     GNUNET_break (0);
543     GNUNET_SERVICE_client_drop (c->client);
544     return;
545   }
546   op = GNUNET_CONTAINER_multihashmap_get (c->ports,
547                                           &pmsg->port);
548   if (NULL == op)
549   {
550     GNUNET_break (0);
551     GNUNET_SERVICE_client_drop (c->client);
552     return;
553   }
554   GNUNET_assert (GNUNET_YES ==
555                  GNUNET_CONTAINER_multihashmap_remove (c->ports,
556                                                        &op->port,
557                                                        op));
558   GNUNET_assert (GNUNET_YES ==
559                  GNUNET_CONTAINER_multihashmap_remove (open_ports,
560                                                        &op->h_port,
561                                                        op));
562   GNUNET_free (op);
563   GNUNET_SERVICE_client_continue (c->client);
564 }
565
566
567 /**
568  * Handler for requests for us creating a new channel to another peer and port.
569  *
570  * @param cls Identification of the client.
571  * @param tcm The actual message.
572  */
573 static void
574 handle_channel_create (void *cls,
575                        const struct GNUNET_CADET_LocalChannelCreateMessage *tcm)
576 {
577   struct CadetClient *c = cls;
578   struct CadetChannel *ch;
579
580   if (ntohl (tcm->ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
581   {
582     /* Channel ID not in allowed range. */
583     GNUNET_break (0);
584     GNUNET_SERVICE_client_drop (c->client);
585     return;
586   }
587   ch = lookup_channel (c,
588                        tcm->ccn);
589   if (NULL != ch)
590   {
591     /* Channel ID already in use. Not allowed. */
592     GNUNET_break (0);
593     GNUNET_SERVICE_client_drop (c->client);
594     return;
595   }
596   LOG (GNUNET_ERROR_TYPE_DEBUG,
597        "New channel to %s at port %s requested by %s\n",
598        GNUNET_i2s (&tcm->peer),
599        GNUNET_h2s (&tcm->port),
600        GSC_2s (c));
601
602   /* Create channel */
603   ch = GCCH_channel_local_new (c,
604                                tcm->ccn,
605                                GCP_get (&tcm->peer,
606                                         GNUNET_YES),
607                                &tcm->port,
608                                ntohl (tcm->opt));
609   if (NULL == ch)
610   {
611     GNUNET_break (0);
612     GNUNET_SERVICE_client_drop (c->client);
613     return;
614   }
615   GNUNET_assert (GNUNET_YES ==
616                  GNUNET_CONTAINER_multihashmap32_put (c->channels,
617                                                       ntohl (
618                                                         tcm->ccn.
619                                                         channel_of_client),
620                                                       ch,
621                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
622
623   GNUNET_SERVICE_client_continue (c->client);
624 }
625
626
627 /**
628  * Handler for requests of destroying an existing channel.
629  *
630  * @param cls client identification of the client
631  * @param msg the actual message
632  */
633 static void
634 handle_channel_destroy (void *cls,
635                         const struct
636                         GNUNET_CADET_LocalChannelDestroyMessage *msg)
637 {
638   struct CadetClient *c = cls;
639   struct CadetChannel *ch;
640
641   ch = lookup_channel (c,
642                        msg->ccn);
643   if (NULL == ch)
644   {
645     /* Client attempted to destroy unknown channel.
646        Can happen if the other side went down at the same time.*/
647     LOG (GNUNET_ERROR_TYPE_DEBUG,
648          "%s tried to destroy unknown channel %X\n",
649          GSC_2s (c),
650          (uint32_t) ntohl (msg->ccn.channel_of_client));
651     GNUNET_SERVICE_client_continue (c->client);
652     return;
653   }
654   LOG (GNUNET_ERROR_TYPE_DEBUG,
655        "%s is destroying %s\n",
656        GSC_2s (c),
657        GCCH_2s (ch));
658   GNUNET_assert (GNUNET_YES ==
659                  GNUNET_CONTAINER_multihashmap32_remove (c->channels,
660                                                          ntohl (
661                                                            msg->ccn.
662                                                            channel_of_client),
663                                                          ch));
664   GCCH_channel_local_destroy (ch,
665                               c,
666                               msg->ccn);
667   GNUNET_SERVICE_client_continue (c->client);
668 }
669
670
671 /**
672  * Check for client traffic data message is well-formed.
673  *
674  * @param cls identification of the client
675  * @param msg the actual message
676  * @return #GNUNET_OK if @a msg is OK, #GNUNET_SYSERR if not
677  */
678 static int
679 check_local_data (void *cls,
680                   const struct GNUNET_CADET_LocalData *msg)
681 {
682   size_t payload_size;
683   size_t payload_claimed_size;
684   const char *buf;
685   struct GNUNET_MessageHeader pa;
686
687   /* FIXME: what is the format we shall allow for @a msg?
688      ONE payload item or multiple? Seems current cadet_api
689      at least in theory allows more than one. Next-gen
690      cadet_api will likely no more, so we could then
691      simplify this mess again. *//* Sanity check for message size */payload_size = ntohs (msg->header.size) - sizeof(*msg);
692   buf = (const char *) &msg[1];
693   while (payload_size >= sizeof(struct GNUNET_MessageHeader))
694   {
695     /* need to memcpy() for alignment */
696     GNUNET_memcpy (&pa,
697                    buf,
698                    sizeof(pa));
699     payload_claimed_size = ntohs (pa.size);
700     if ((payload_size < payload_claimed_size) ||
701         (payload_claimed_size < sizeof(struct GNUNET_MessageHeader)) ||
702         (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE < payload_claimed_size))
703     {
704       GNUNET_break (0);
705       LOG (GNUNET_ERROR_TYPE_DEBUG,
706            "Local data of %u total size had sub-message %u at %u with %u bytes\n",
707            ntohs (msg->header.size),
708            ntohs (pa.type),
709            (unsigned int) (buf - (const char *) &msg[1]),
710            (unsigned int) payload_claimed_size);
711       return GNUNET_SYSERR;
712     }
713     payload_size -= payload_claimed_size;
714     buf += payload_claimed_size;
715   }
716   if (0 != payload_size)
717   {
718     GNUNET_break_op (0);
719     return GNUNET_SYSERR;
720   }
721   return GNUNET_OK;
722 }
723
724
725 /**
726  * Handler for client payload traffic to be send on a channel to
727  * another peer.
728  *
729  * @param cls identification of the client
730  * @param msg the actual message
731  */
732 static void
733 handle_local_data (void *cls,
734                    const struct GNUNET_CADET_LocalData *msg)
735 {
736   struct CadetClient *c = cls;
737   struct CadetChannel *ch;
738   size_t payload_size;
739   const char *buf;
740
741   ch = lookup_channel (c,
742                        msg->ccn);
743   if (NULL == ch)
744   {
745     /* Channel does not exist (anymore) */
746     LOG (GNUNET_ERROR_TYPE_WARNING,
747          "Dropping payload for channel %u from client (channel unknown, other endpoint may have disconnected)\n",
748          (unsigned int) ntohl (msg->ccn.channel_of_client));
749     GNUNET_SERVICE_client_continue (c->client);
750     return;
751   }
752   payload_size = ntohs (msg->header.size) - sizeof(*msg);
753   GNUNET_STATISTICS_update (stats,
754                             "# payload received from clients",
755                             payload_size,
756                             GNUNET_NO);
757   buf = (const char *) &msg[1];
758   LOG (GNUNET_ERROR_TYPE_DEBUG,
759        "Received %u bytes payload from %s for %s\n",
760        (unsigned int) payload_size,
761        GSC_2s (c),
762        GCCH_2s (ch));
763   if (GNUNET_OK !=
764       GCCH_handle_local_data (ch,
765                               msg->ccn,
766                               buf,
767                               payload_size))
768   {
769     GNUNET_break (0);
770     GNUNET_SERVICE_client_drop (c->client);
771     return;
772   }
773   GNUNET_SERVICE_client_continue (c->client);
774 }
775
776
777 /**
778  * Handler for client's ACKs for payload traffic.
779  *
780  * @param cls identification of the client.
781  * @param msg The actual message.
782  */
783 static void
784 handle_local_ack (void *cls,
785                   const struct GNUNET_CADET_LocalAck *msg)
786 {
787   struct CadetClient *c = cls;
788   struct CadetChannel *ch;
789
790   ch = lookup_channel (c,
791                        msg->ccn);
792   if (NULL == ch)
793   {
794     /* Channel does not exist (anymore) */
795     LOG (GNUNET_ERROR_TYPE_WARNING,
796          "Ignoring local ACK for channel %u from client (channel unknown, other endpoint may have disconnected)\n",
797          (unsigned int) ntohl (msg->ccn.channel_of_client));
798     GNUNET_SERVICE_client_continue (c->client);
799     return;
800   }
801   LOG (GNUNET_ERROR_TYPE_DEBUG,
802        "Got a local ACK from %s for %s\n",
803        GSC_2s (c),
804        GCCH_2s (ch));
805   GCCH_handle_local_ack (ch,
806                          msg->ccn);
807   GNUNET_SERVICE_client_continue (c->client);
808 }
809
810
811 /**
812  * Iterator over all peers to send a monitoring client info about each peer.
813  *
814  * @param cls Closure ().
815  * @param peer Peer ID (tunnel remote peer).
816  * @param value Peer info.
817  * @return #GNUNET_YES, to keep iterating.
818  */
819 static int
820 get_all_peers_iterator (void *cls,
821                         const struct GNUNET_PeerIdentity *peer,
822                         void *value)
823 {
824   struct CadetClient *c = cls;
825   struct CadetPeer *p = value;
826   struct GNUNET_MQ_Envelope *env;
827   struct GNUNET_CADET_LocalInfoPeers *msg;
828
829   env = GNUNET_MQ_msg (msg,
830                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
831   msg->destination = *peer;
832   msg->paths = htons (GCP_count_paths (p));
833   msg->tunnel = htons (NULL != GCP_get_tunnel (p,
834                                                GNUNET_NO));
835   msg->best_path_length = htonl (0);  // FIXME: get length of shortest known path!
836   GNUNET_MQ_send (c->mq,
837                   env);
838   return GNUNET_YES;
839 }
840
841
842 /**
843  * Handler for client's INFO PEERS request.
844  *
845  * @param cls Identification of the client.
846  * @param message The actual message.
847  */
848 static void
849 handle_get_peers (void *cls,
850                   const struct GNUNET_MessageHeader *message)
851 {
852   struct CadetClient *c = cls;
853   struct GNUNET_MQ_Envelope *env;
854   struct GNUNET_MessageHeader *reply;
855
856   GCP_iterate_all (&get_all_peers_iterator,
857                    c);
858   env = GNUNET_MQ_msg (reply,
859                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS_END);
860   GNUNET_MQ_send (c->mq,
861                   env);
862   GNUNET_SERVICE_client_continue (c->client);
863 }
864
865
866 /**
867  * Iterator over all paths of a peer to build an InfoPeer message.
868  * Message contains blocks of peers, first not included.
869  *
870  * @param cls message queue for transmission
871  * @param path Path itself
872  * @param off offset of the peer on @a path
873  * @return #GNUNET_YES if should keep iterating.
874  *         #GNUNET_NO otherwise.
875  */
876 static int
877 path_info_iterator (void *cls,
878                     struct CadetPeerPath *path,
879                     unsigned int off)
880 {
881   struct GNUNET_MQ_Handle *mq = cls;
882   struct GNUNET_MQ_Envelope *env;
883   struct GNUNET_CADET_LocalInfoPath *resp;
884   struct GNUNET_PeerIdentity *id;
885   size_t path_size;
886   unsigned int path_length;
887
888   path_length = GCPP_get_length (path);
889   path_size = sizeof(struct GNUNET_PeerIdentity) * path_length;
890   if (sizeof(*resp) + path_size > UINT16_MAX)
891   {
892     /* try just giving the relevant path */
893     path_length = GNUNET_MIN ((UINT16_MAX - sizeof(*resp)) / sizeof(struct
894                                                                     GNUNET_PeerIdentity),
895                               off);
896     path_size = sizeof(struct GNUNET_PeerIdentity) * path_length;
897   }
898   if (sizeof(*resp) + path_size > UINT16_MAX)
899   {
900     LOG (GNUNET_ERROR_TYPE_WARNING,
901          "Path of %u entries is too long for info message\n",
902          path_length);
903     return GNUNET_YES;
904   }
905   env = GNUNET_MQ_msg_extra (resp,
906                              path_size,
907                              GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PATH);
908   id = (struct GNUNET_PeerIdentity *) &resp[1];
909
910   /* Don't copy first peer.  First peer is always the local one.  Last
911    * peer is always the destination (leave as 0, EOL).
912    */
913   for (unsigned int i = 0; i < path_length; i++)
914     id[i] = *GCP_get_id (GCPP_get_peer_at_offset (path,
915                                                   i));
916   resp->off = htonl (off);
917   GNUNET_MQ_send (mq,
918                   env);
919   return GNUNET_YES;
920 }
921
922
923 /**
924  * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PATH request.
925  *
926  * @param cls Identification of the client.
927  * @param msg The actual message.
928  */
929 static void
930 handle_show_path (void *cls,
931                   const struct GNUNET_CADET_RequestPathInfoMessage *msg)
932 {
933   struct CadetClient *c = cls;
934   struct CadetPeer *p;
935   struct GNUNET_MQ_Envelope *env;
936   struct GNUNET_MessageHeader *resp;
937
938   p = GCP_get (&msg->peer,
939                GNUNET_NO);
940   if (NULL != p)
941     GCP_iterate_indirect_paths (p,
942                                 &path_info_iterator,
943                                 c->mq);
944   env = GNUNET_MQ_msg (resp,
945                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PATH_END);
946   GNUNET_MQ_send (c->mq,
947                   env);
948   GNUNET_SERVICE_client_continue (c->client);
949 }
950
951
952 /**
953  * Iterator over all tunnels to send a monitoring client info about each tunnel.
954  *
955  * @param cls Closure ().
956  * @param peer Peer ID (tunnel remote peer).
957  * @param value a `struct CadetPeer`
958  * @return #GNUNET_YES, to keep iterating.
959  */
960 static int
961 get_all_tunnels_iterator (void *cls,
962                           const struct GNUNET_PeerIdentity *peer,
963                           void *value)
964 {
965   struct CadetClient *c = cls;
966   struct CadetPeer *p = value;
967   struct GNUNET_MQ_Envelope *env;
968   struct GNUNET_CADET_LocalInfoTunnel *msg;
969   struct CadetTunnel *t;
970
971   t = GCP_get_tunnel (p,
972                       GNUNET_NO);
973   if (NULL == t)
974     return GNUNET_YES;
975   env = GNUNET_MQ_msg (msg,
976                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
977   msg->destination = *peer;
978   msg->channels = htonl (GCT_count_channels (t));
979   msg->connections = htonl (GCT_count_any_connections (t));
980   msg->cstate = htons (0);
981   msg->estate = htons ((uint16_t) GCT_get_estate (t));
982   GNUNET_MQ_send (c->mq,
983                   env);
984   return GNUNET_YES;
985 }
986
987
988 /**
989  * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_TUNNELS request.
990  *
991  * @param cls client Identification of the client.
992  * @param message The actual message.
993  */
994 static void
995 handle_info_tunnels (void *cls,
996                      const struct GNUNET_MessageHeader *message)
997 {
998   struct CadetClient *c = cls;
999   struct GNUNET_MQ_Envelope *env;
1000   struct GNUNET_MessageHeader *reply;
1001
1002   GCP_iterate_all (&get_all_tunnels_iterator,
1003                    c);
1004   env = GNUNET_MQ_msg (reply,
1005                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS_END);
1006   GNUNET_MQ_send (c->mq,
1007                   env);
1008   GNUNET_SERVICE_client_continue (c->client);
1009 }
1010
1011
1012 /**
1013  * Callback called when a client connects to the service.
1014  *
1015  * @param cls closure for the service
1016  * @param client the new client that connected to the service
1017  * @param mq the message queue used to send messages to the client
1018  * @return @a c
1019  */
1020 static void *
1021 client_connect_cb (void *cls,
1022                    struct GNUNET_SERVICE_Client *client,
1023                    struct GNUNET_MQ_Handle *mq)
1024 {
1025   struct CadetClient *c;
1026
1027   c = GNUNET_new (struct CadetClient);
1028   c->client = client;
1029   c->mq = mq;
1030   c->id = next_client_id++; /* overflow not important: just for debug */
1031   c->channels
1032     = GNUNET_CONTAINER_multihashmap32_create (32);
1033   GNUNET_CONTAINER_DLL_insert (clients_head,
1034                                clients_tail,
1035                                c);
1036   GNUNET_STATISTICS_update (stats,
1037                             "# clients",
1038                             +1,
1039                             GNUNET_NO);
1040   LOG (GNUNET_ERROR_TYPE_DEBUG,
1041        "%s connected\n",
1042        GSC_2s (c));
1043   return c;
1044 }
1045
1046
1047 /**
1048  * A channel was destroyed by the other peer. Tell our client.
1049  *
1050  * @param c client that lost a channel
1051  * @param ccn channel identification number for the client
1052  * @param ch the channel object
1053  */
1054 void
1055 GSC_handle_remote_channel_destroy (struct CadetClient *c,
1056                                    struct GNUNET_CADET_ClientChannelNumber ccn,
1057                                    struct CadetChannel *ch)
1058 {
1059   struct GNUNET_MQ_Envelope *env;
1060   struct GNUNET_CADET_LocalChannelDestroyMessage *tdm;
1061
1062   env = GNUNET_MQ_msg (tdm,
1063                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
1064   tdm->ccn = ccn;
1065   GSC_send_to_client (c,
1066                       env);
1067   GNUNET_assert (GNUNET_YES ==
1068                  GNUNET_CONTAINER_multihashmap32_remove (c->channels,
1069                                                          ntohl (
1070                                                            ccn.channel_of_client),
1071                                                          ch));
1072 }
1073
1074
1075 /**
1076  * A client that created a loose channel that was not bound to a port
1077  * disconnected, drop it from the #loose_channels list.
1078  *
1079  * @param h_port the hashed port the channel was trying to bind to
1080  * @param ch the channel that was lost
1081  */
1082 void
1083 GSC_drop_loose_channel (const struct GNUNET_HashCode *h_port,
1084                         struct CadetChannel *ch)
1085 {
1086   GNUNET_assert (GNUNET_YES ==
1087                  GNUNET_CONTAINER_multihashmap_remove (loose_channels,
1088                                                        h_port,
1089                                                        ch));
1090 }
1091
1092
1093 /**
1094  * Iterator for deleting each channel whose client endpoint disconnected.
1095  *
1096  * @param cls Closure (client that has disconnected).
1097  * @param key The local channel id in host byte order
1098  * @param value The value stored at the key (channel to destroy).
1099  * @return #GNUNET_OK, keep iterating.
1100  */
1101 static int
1102 channel_destroy_iterator (void *cls,
1103                           uint32_t key,
1104                           void *value)
1105 {
1106   struct CadetClient *c = cls;
1107   struct GNUNET_CADET_ClientChannelNumber ccn;
1108   struct CadetChannel *ch = value;
1109
1110   LOG (GNUNET_ERROR_TYPE_DEBUG,
1111        "Destroying %s, due to %s disconnecting.\n",
1112        GCCH_2s (ch),
1113        GSC_2s (c));
1114   ccn.channel_of_client = htonl (key);
1115   GCCH_channel_local_destroy (ch,
1116                               c,
1117                               ccn);
1118   GNUNET_assert (GNUNET_YES ==
1119                  GNUNET_CONTAINER_multihashmap32_remove (c->channels,
1120                                                          key,
1121                                                          ch));
1122   return GNUNET_OK;
1123 }
1124
1125
1126 /**
1127  * Remove client's ports from the global hashmap on disconnect.
1128  *
1129  * @param cls the `struct CadetClient`
1130  * @param port the port.
1131  * @param value the `struct OpenPort` to remove
1132  * @return #GNUNET_OK, keep iterating.
1133  */
1134 static int
1135 client_release_ports (void *cls,
1136                       const struct GNUNET_HashCode *port,
1137                       void *value)
1138 {
1139   struct CadetClient *c = cls;
1140   struct OpenPort *op = value;
1141
1142   GNUNET_assert (c == op->c);
1143   LOG (GNUNET_ERROR_TYPE_DEBUG,
1144        "Closing port %s due to %s disconnect.\n",
1145        GNUNET_h2s (port),
1146        GSC_2s (c));
1147   GNUNET_assert (GNUNET_YES ==
1148                  GNUNET_CONTAINER_multihashmap_remove (open_ports,
1149                                                        &op->h_port,
1150                                                        op));
1151   GNUNET_assert (GNUNET_YES ==
1152                  GNUNET_CONTAINER_multihashmap_remove (c->ports,
1153                                                        port,
1154                                                        op));
1155   GNUNET_free (op);
1156   return GNUNET_OK;
1157 }
1158
1159
1160 /**
1161  * Callback called when a client disconnected from the service
1162  *
1163  * @param cls closure for the service
1164  * @param client the client that disconnected
1165  * @param internal_cls should be equal to @a c
1166  */
1167 static void
1168 client_disconnect_cb (void *cls,
1169                       struct GNUNET_SERVICE_Client *client,
1170                       void *internal_cls)
1171 {
1172   struct CadetClient *c = internal_cls;
1173
1174   GNUNET_assert (c->client == client);
1175   LOG (GNUNET_ERROR_TYPE_DEBUG,
1176        "%s is disconnecting.\n",
1177        GSC_2s (c));
1178   if (NULL != c->channels)
1179   {
1180     GNUNET_CONTAINER_multihashmap32_iterate (c->channels,
1181                                              &channel_destroy_iterator,
1182                                              c);
1183     GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap32_size (c->channels));
1184     GNUNET_CONTAINER_multihashmap32_destroy (c->channels);
1185   }
1186   if (NULL != c->ports)
1187   {
1188     GNUNET_CONTAINER_multihashmap_iterate (c->ports,
1189                                            &client_release_ports,
1190                                            c);
1191     GNUNET_CONTAINER_multihashmap_destroy (c->ports);
1192   }
1193   GNUNET_CONTAINER_DLL_remove (clients_head,
1194                                clients_tail,
1195                                c);
1196   GNUNET_STATISTICS_update (stats,
1197                             "# clients",
1198                             -1,
1199                             GNUNET_NO);
1200   GNUNET_free (c);
1201   if ((NULL == clients_head) &&
1202       (GNUNET_YES == shutting_down))
1203     shutdown_rest ();
1204 }
1205
1206
1207 /**
1208  * Setup CADET internals.
1209  *
1210  * @param cls closure
1211  * @param server the initialized server
1212  * @param c configuration to use
1213  */
1214 static void
1215 run (void *cls,
1216      const struct GNUNET_CONFIGURATION_Handle *c,
1217      struct GNUNET_SERVICE_Handle *service)
1218 {
1219   cfg = c;
1220   if (GNUNET_OK !=
1221       GNUNET_CONFIGURATION_get_value_number (c,
1222                                              "CADET",
1223                                              "RATCHET_MESSAGES",
1224                                              &ratchet_messages))
1225   {
1226     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1227                                "CADET",
1228                                "RATCHET_MESSAGES",
1229                                "needs to be a number");
1230     ratchet_messages = 64;
1231   }
1232   if (GNUNET_OK !=
1233       GNUNET_CONFIGURATION_get_value_time (c,
1234                                            "CADET",
1235                                            "RATCHET_TIME",
1236                                            &ratchet_time))
1237   {
1238     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1239                                "CADET",
1240                                "RATCHET_TIME",
1241                                "need delay value");
1242     ratchet_time = GNUNET_TIME_UNIT_HOURS;
1243   }
1244   if (GNUNET_OK !=
1245       GNUNET_CONFIGURATION_get_value_time (c,
1246                                            "CADET",
1247                                            "REFRESH_CONNECTION_TIME",
1248                                            &keepalive_period))
1249   {
1250     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1251                                "CADET",
1252                                "REFRESH_CONNECTION_TIME",
1253                                "need delay value");
1254     keepalive_period = GNUNET_TIME_UNIT_MINUTES;
1255   }
1256   if (GNUNET_OK !=
1257       GNUNET_CONFIGURATION_get_value_number (c,
1258                                              "CADET",
1259                                              "DROP_PERCENT",
1260                                              &drop_percent))
1261   {
1262     drop_percent = 0;
1263   }
1264   else
1265   {
1266     LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1267     LOG (GNUNET_ERROR_TYPE_WARNING, "Cadet is running with DROP enabled.\n");
1268     LOG (GNUNET_ERROR_TYPE_WARNING, "This is NOT a good idea!\n");
1269     LOG (GNUNET_ERROR_TYPE_WARNING, "Remove DROP_PERCENT from config file.\n");
1270     LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1271   }
1272   my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c);
1273   if (NULL == my_private_key)
1274   {
1275     GNUNET_break (0);
1276     GNUNET_SCHEDULER_shutdown ();
1277     return;
1278   }
1279   GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
1280                                       &my_full_id.public_key);
1281   stats = GNUNET_STATISTICS_create ("cadet",
1282                                     c);
1283   GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1284                                  NULL);
1285   ats_ch = GNUNET_ATS_connectivity_init (c);
1286   /* FIXME: optimize code to allow GNUNET_YES here! */
1287   open_ports = GNUNET_CONTAINER_multihashmap_create (16,
1288                                                      GNUNET_NO);
1289   loose_channels = GNUNET_CONTAINER_multihashmap_create (16,
1290                                                          GNUNET_NO);
1291   peers = GNUNET_CONTAINER_multipeermap_create (16,
1292                                                 GNUNET_YES);
1293   connections = GNUNET_CONTAINER_multishortmap_create (256,
1294                                                        GNUNET_YES);
1295   GCH_init (c);
1296   GCD_init (c);
1297   GCO_init (c);
1298   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1299               "CADET started for peer %s\n",
1300               GNUNET_i2s (&my_full_id));
1301 }
1302
1303
1304 /**
1305  * Define "main" method using service macro.
1306  */
1307 GNUNET_SERVICE_MAIN
1308   ("cadet",
1309   GNUNET_SERVICE_OPTION_NONE,
1310   &run,
1311   &client_connect_cb,
1312   &client_disconnect_cb,
1313   NULL,
1314   GNUNET_MQ_hd_fixed_size (port_open,
1315                            GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN,
1316                            struct GNUNET_CADET_PortMessage,
1317                            NULL),
1318   GNUNET_MQ_hd_fixed_size (port_close,
1319                            GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE,
1320                            struct GNUNET_CADET_PortMessage,
1321                            NULL),
1322   GNUNET_MQ_hd_fixed_size (channel_create,
1323                            GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE,
1324                            struct GNUNET_CADET_LocalChannelCreateMessage,
1325                            NULL),
1326   GNUNET_MQ_hd_fixed_size (channel_destroy,
1327                            GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY,
1328                            struct GNUNET_CADET_LocalChannelDestroyMessage,
1329                            NULL),
1330   GNUNET_MQ_hd_var_size (local_data,
1331                          GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
1332                          struct GNUNET_CADET_LocalData,
1333                          NULL),
1334   GNUNET_MQ_hd_fixed_size (local_ack,
1335                            GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
1336                            struct GNUNET_CADET_LocalAck,
1337                            NULL),
1338   GNUNET_MQ_hd_fixed_size (get_peers,
1339                            GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PEERS,
1340                            struct GNUNET_MessageHeader,
1341                            NULL),
1342   GNUNET_MQ_hd_fixed_size (show_path,
1343                            GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PATH,
1344                            struct GNUNET_CADET_RequestPathInfoMessage,
1345                            NULL),
1346   GNUNET_MQ_hd_fixed_size (info_tunnels,
1347                            GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_TUNNELS,
1348                            struct GNUNET_MessageHeader,
1349                            NULL),
1350   GNUNET_MQ_handler_end ());
1351
1352 /* end of gnunet-service-cadet-new.c */