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