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