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