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