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