4568d2733fe73888dda40fda265d96c73a47155c
[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;
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   
896   
897   resp->offset = htons(off);
898   resp->finished_with_paths = htons(0);
899   
900   id = (struct GNUNET_PeerIdentity *) &resp[1];
901
902   /* Don't copy first peer.  First peer is always the local one.  Last
903    * peer is always the destination (leave as 0, EOL).
904    */
905   for (i = 0; i <= off; i++)
906     id[i] = *GCP_get_id (GCPP_get_peer_at_offset (path,
907                                                   i));
908   GNUNET_MQ_send (mq,
909                   env);
910   return GNUNET_YES;
911 }
912
913 /**
914  * Getting summary information about the number of paths and if a tunnel exists, 
915  * and the indirect paths to a peer, if there are ones.
916  *
917  * @param cls Closure ().
918  * @param peer Peer ID (tunnel remote peer).
919  * @param value Peer info.
920  * @return #GNUNET_YES, to keep iterating.
921  */
922 static void
923 get_peer_info (void *cls,
924                 const struct GNUNET_PeerIdentity *peer,
925                 struct CadetPeer *p)
926 {
927   struct CadetClient *c = cls;
928   struct GNUNET_MQ_Envelope *env;
929   struct GNUNET_CADET_LocalInfoPeer *msg;
930   
931   env = GNUNET_MQ_msg (msg,
932                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
933   msg->offset = htons(0);
934   msg->destination = *peer;
935   msg->paths = htons (GCP_count_paths (p));
936   msg->tunnel = htons (NULL != GCP_get_tunnel (p,
937                                                GNUNET_NO));
938   msg->finished_with_paths = htons(0);
939   GNUNET_MQ_send (c->mq,
940                   env);
941   GCP_iterate_indirect_paths (p,
942                               &path_info_iterator,
943                               c->mq);  
944 }
945
946
947 /**
948  * Handler for client's SHOW_PEER request.
949  *
950  * @param cls Identification of the client.
951  * @param msg The actual message.
952  */
953 static void
954 handle_show_peer (void *cls,
955                   const struct GNUNET_CADET_LocalInfo *msg)
956 {
957   struct CadetClient *c = cls;
958   struct CadetPeer *p;
959   struct GNUNET_MQ_Envelope *env;
960   struct GNUNET_CADET_LocalInfoPeer *resp;
961
962   p = GCP_get (&msg->peer,
963                GNUNET_NO);
964   if (NULL != p){
965     get_peer_info(c, &(msg->peer), p);  
966   }
967   
968   
969   env = GNUNET_MQ_msg (resp,
970                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
971   resp->finished_with_paths = htons(1);
972   resp->destination = msg->peer;
973   
974   GNUNET_MQ_send (c->mq,
975                   env);
976   
977   GNUNET_SERVICE_client_continue (c->client);
978 }
979
980
981 /**
982  * Iterator over all tunnels to send a monitoring client info about each tunnel.
983  *
984  * @param cls Closure ().
985  * @param peer Peer ID (tunnel remote peer).
986  * @param value a `struct CadetPeer`
987  * @return #GNUNET_YES, to keep iterating.
988  */
989 static int
990 get_all_tunnels_iterator (void *cls,
991                           const struct GNUNET_PeerIdentity *peer,
992                           void *value)
993 {
994   struct CadetClient *c = cls;
995   struct CadetPeer *p = value;
996   struct GNUNET_MQ_Envelope *env;
997   struct GNUNET_CADET_LocalInfoTunnel *msg;
998   struct CadetTunnel *t;
999
1000   t = GCP_get_tunnel (p,
1001                       GNUNET_NO);
1002   if (NULL == t)
1003     return GNUNET_YES;
1004   env = GNUNET_MQ_msg (msg,
1005                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
1006   msg->destination = *peer;
1007   msg->channels = htonl (GCT_count_channels (t));
1008   msg->connections = htonl (GCT_count_any_connections (t));
1009   msg->cstate = htons (0);
1010   msg->estate = htons ((uint16_t) GCT_get_estate (t));
1011   GNUNET_MQ_send (c->mq,
1012                   env);
1013   return GNUNET_YES;
1014 }
1015
1016
1017 /**
1018  * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS request.
1019  *
1020  * @param cls client Identification of the client.
1021  * @param message The actual message.
1022  */
1023 static void
1024 handle_info_tunnels (void *cls,
1025                      const struct GNUNET_MessageHeader *message)
1026 {
1027   struct CadetClient *c = cls;
1028   struct GNUNET_MQ_Envelope *env;
1029   struct GNUNET_MessageHeader *reply;
1030
1031   GCP_iterate_all (&get_all_tunnels_iterator,
1032                    c);
1033   env = GNUNET_MQ_msg (reply,
1034                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
1035   GNUNET_MQ_send (c->mq,
1036                   env);
1037   GNUNET_SERVICE_client_continue (c->client);
1038 }
1039
1040
1041 /**
1042  * Update the message with information about the connection.
1043  *
1044  * @param cls a `struct GNUNET_CADET_LocalInfoTunnel` message to update
1045  * @param ct a connection about which we should store information in @a cls
1046  */
1047 static void
1048 iter_connection (void *cls,
1049                  struct CadetTConnection *ct)
1050 {
1051   struct GNUNET_CADET_LocalInfoTunnel *msg = cls;
1052   struct CadetConnection *cc = ct->cc;
1053   struct GNUNET_CADET_ConnectionTunnelIdentifier *h;
1054
1055   h = (struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1];
1056   h[msg->connections++] = *(GCC_get_id (cc));
1057 }
1058
1059
1060 /**
1061  * Update the message with information about the channel.
1062  *
1063  * @param cls a `struct GNUNET_CADET_LocalInfoTunnel` message to update
1064  * @param ch a channel about which we should store information in @a cls
1065  */
1066 static void
1067 iter_channel (void *cls,
1068               struct CadetChannel *ch)
1069 {
1070   struct GNUNET_CADET_LocalInfoTunnel *msg = cls;
1071   struct GNUNET_CADET_ConnectionTunnelIdentifier *h = (struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1];
1072   struct GNUNET_CADET_ChannelTunnelNumber *chn
1073     = (struct GNUNET_CADET_ChannelTunnelNumber *) &h[msg->connections];
1074
1075   chn[msg->channels++] = GCCH_get_id (ch);
1076 }
1077
1078
1079 /**
1080  * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL request.
1081  *
1082  * @param cls Identification of the client.
1083  * @param msg The actual message.
1084  */
1085 static void
1086 handle_info_tunnel (void *cls,
1087                     const struct GNUNET_CADET_LocalInfo *msg)
1088 {
1089   struct CadetClient *c = cls;
1090   struct GNUNET_MQ_Envelope *env;
1091   struct GNUNET_CADET_LocalInfoTunnel *resp;
1092   struct CadetTunnel *t;
1093   struct CadetPeer *p;
1094   unsigned int ch_n;
1095   unsigned int c_n;
1096
1097   p = GCP_get (&msg->peer,
1098                GNUNET_NO);
1099   t = GCP_get_tunnel (p,
1100                       GNUNET_NO);
1101   if (NULL == t)
1102   {
1103     /* We don't know the tunnel */
1104     struct GNUNET_MQ_Envelope *env;
1105     struct GNUNET_CADET_LocalInfoTunnel *warn;
1106
1107     LOG (GNUNET_ERROR_TYPE_INFO,
1108          "Tunnel to %s unknown\n",
1109          GNUNET_i2s_full (&msg->peer));
1110     env = GNUNET_MQ_msg (warn,
1111                          GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
1112     warn->destination = msg->peer;
1113     GNUNET_MQ_send (c->mq,
1114                     env);
1115     GNUNET_SERVICE_client_continue (c->client);
1116     return;
1117   }
1118
1119   /* Initialize context */
1120   ch_n = GCT_count_channels (t);
1121   c_n = GCT_count_any_connections (t);
1122   env = GNUNET_MQ_msg_extra (resp,
1123                              c_n * sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier) +
1124                              ch_n * sizeof (struct GNUNET_CADET_ChannelTunnelNumber),
1125                              GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
1126   resp->destination = msg->peer;
1127   /* Do not reorder! #iter_channel needs counters in HBO! */
1128   GCT_iterate_connections (t,
1129                            &iter_connection,
1130                            resp);
1131   GCT_iterate_channels (t,
1132                         &iter_channel,
1133                         resp);
1134   resp->connections = htonl (resp->connections);
1135   resp->channels = htonl (resp->channels);
1136   resp->cstate = htons (0);
1137   resp->estate = htons (GCT_get_estate (t));
1138   GNUNET_MQ_send (c->mq,
1139                   env);
1140   GNUNET_SERVICE_client_continue (c->client);
1141 }
1142
1143
1144 /**
1145  * Iterator over all peers to dump info for each peer.
1146  *
1147  * @param cls Closure (unused).
1148  * @param peer Peer ID (tunnel remote peer).
1149  * @param value Peer info.
1150  *
1151  * @return #GNUNET_YES, to keep iterating.
1152  */
1153 static int
1154 show_peer_iterator (void *cls,
1155                     const struct GNUNET_PeerIdentity *peer,
1156                     void *value)
1157 {
1158   struct CadetPeer *p = value;
1159   struct CadetTunnel *t;
1160
1161   t = GCP_get_tunnel (p,
1162                       GNUNET_NO);
1163   if (NULL != t)
1164     GCT_debug (t,
1165                GNUNET_ERROR_TYPE_ERROR);
1166   LOG (GNUNET_ERROR_TYPE_ERROR, "\n");
1167   return GNUNET_YES;
1168 }
1169
1170
1171 /**
1172  * Handler for client's INFO_DUMP request.
1173  *
1174  * @param cls Identification of the client.
1175  * @param message The actual message.
1176  */
1177 static void
1178 handle_info_dump (void *cls,
1179                   const struct GNUNET_MessageHeader *message)
1180 {
1181   struct CadetClient *c = cls;
1182
1183   LOG (GNUNET_ERROR_TYPE_INFO,
1184        "Received dump info request from client %u\n",
1185        c->id);
1186
1187   LOG (GNUNET_ERROR_TYPE_ERROR,
1188        "*************************** DUMP START ***************************\n");
1189   for (struct CadetClient *ci = clients_head;
1190        NULL != ci;
1191        ci = ci->next)
1192   {
1193     LOG (GNUNET_ERROR_TYPE_ERROR,
1194          "Client %u (%p), handle: %p, ports: %u, channels: %u\n",
1195          ci->id,
1196          ci,
1197          ci->client,
1198          (NULL != c->ports)
1199          ? GNUNET_CONTAINER_multihashmap_size (ci->ports)
1200          : 0,
1201          GNUNET_CONTAINER_multihashmap32_size (ci->channels));
1202   }
1203   LOG (GNUNET_ERROR_TYPE_ERROR, "***************************\n");
1204   GCP_iterate_all (&show_peer_iterator,
1205                    NULL);
1206
1207   LOG (GNUNET_ERROR_TYPE_ERROR,
1208        "**************************** DUMP END ****************************\n");
1209
1210   GNUNET_SERVICE_client_continue (c->client);
1211 }
1212
1213
1214
1215 /**
1216  * Callback called when a client connects to the service.
1217  *
1218  * @param cls closure for the service
1219  * @param client the new client that connected to the service
1220  * @param mq the message queue used to send messages to the client
1221  * @return @a c
1222  */
1223 static void *
1224 client_connect_cb (void *cls,
1225                    struct GNUNET_SERVICE_Client *client,
1226                    struct GNUNET_MQ_Handle *mq)
1227 {
1228   struct CadetClient *c;
1229
1230   c = GNUNET_new (struct CadetClient);
1231   c->client = client;
1232   c->mq = mq;
1233   c->id = next_client_id++; /* overflow not important: just for debug */
1234   c->channels
1235     = GNUNET_CONTAINER_multihashmap32_create (32);
1236   GNUNET_CONTAINER_DLL_insert (clients_head,
1237                                clients_tail,
1238                                c);
1239   GNUNET_STATISTICS_update (stats,
1240                             "# clients",
1241                             +1,
1242                             GNUNET_NO);
1243   LOG (GNUNET_ERROR_TYPE_DEBUG,
1244        "%s connected\n",
1245        GSC_2s (c));
1246   return c;
1247 }
1248
1249
1250 /**
1251  * A channel was destroyed by the other peer. Tell our client.
1252  *
1253  * @param c client that lost a channel
1254  * @param ccn channel identification number for the client
1255  * @param ch the channel object
1256  */
1257 void
1258 GSC_handle_remote_channel_destroy (struct CadetClient *c,
1259                                    struct GNUNET_CADET_ClientChannelNumber ccn,
1260                                    struct CadetChannel *ch)
1261 {
1262   struct GNUNET_MQ_Envelope *env;
1263   struct GNUNET_CADET_LocalChannelDestroyMessage *tdm;
1264
1265   env = GNUNET_MQ_msg (tdm,
1266                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
1267   tdm->ccn = ccn;
1268   GSC_send_to_client (c,
1269                       env);
1270   GNUNET_assert (GNUNET_YES ==
1271                  GNUNET_CONTAINER_multihashmap32_remove (c->channels,
1272                                                          ntohl (ccn.channel_of_client),
1273                                                          ch));
1274 }
1275
1276
1277 /**
1278  * A client that created a loose channel that was not bound to a port
1279  * disconnected, drop it from the #loose_channels list.
1280  *
1281  * @param h_port the hashed port the channel was trying to bind to
1282  * @param ch the channel that was lost
1283  */
1284 void
1285 GSC_drop_loose_channel (const struct GNUNET_HashCode *h_port,
1286                         struct CadetChannel *ch)
1287 {
1288   GNUNET_assert (GNUNET_YES ==
1289                  GNUNET_CONTAINER_multihashmap_remove (loose_channels,
1290                                                        h_port,
1291                                                        ch));
1292 }
1293
1294
1295 /**
1296  * Iterator for deleting each channel whose client endpoint disconnected.
1297  *
1298  * @param cls Closure (client that has disconnected).
1299  * @param key The local channel id in host byte order
1300  * @param value The value stored at the key (channel to destroy).
1301  * @return #GNUNET_OK, keep iterating.
1302  */
1303 static int
1304 channel_destroy_iterator (void *cls,
1305                           uint32_t key,
1306                           void *value)
1307 {
1308   struct CadetClient *c = cls;
1309   struct GNUNET_CADET_ClientChannelNumber ccn;
1310   struct CadetChannel *ch = value;
1311
1312   LOG (GNUNET_ERROR_TYPE_DEBUG,
1313        "Destroying %s, due to %s disconnecting.\n",
1314        GCCH_2s (ch),
1315        GSC_2s (c));
1316   ccn.channel_of_client = htonl (key);
1317   GCCH_channel_local_destroy (ch,
1318                               c,
1319                               ccn);
1320   GNUNET_assert (GNUNET_YES ==
1321                  GNUNET_CONTAINER_multihashmap32_remove (c->channels,
1322                                                          key,
1323                                                          ch));
1324   return GNUNET_OK;
1325 }
1326
1327
1328 /**
1329  * Remove client's ports from the global hashmap on disconnect.
1330  *
1331  * @param cls the `struct CadetClient`
1332  * @param port the port.
1333  * @param value the `struct OpenPort` to remove
1334  * @return #GNUNET_OK, keep iterating.
1335  */
1336 static int
1337 client_release_ports (void *cls,
1338                       const struct GNUNET_HashCode *port,
1339                       void *value)
1340 {
1341   struct CadetClient *c = cls;
1342   struct OpenPort *op = value;
1343
1344   GNUNET_assert (c == op->c);
1345   LOG (GNUNET_ERROR_TYPE_DEBUG,
1346        "Closing port %s due to %s disconnect.\n",
1347        GNUNET_h2s (port),
1348        GSC_2s (c));
1349   GNUNET_assert (GNUNET_YES ==
1350                  GNUNET_CONTAINER_multihashmap_remove (open_ports,
1351                                                        &op->h_port,
1352                                                        op));
1353   GNUNET_assert (GNUNET_YES ==
1354                  GNUNET_CONTAINER_multihashmap_remove (c->ports,
1355                                                        port,
1356                                                        op));
1357   GNUNET_free (op);
1358   return GNUNET_OK;
1359 }
1360
1361
1362 /**
1363  * Callback called when a client disconnected from the service
1364  *
1365  * @param cls closure for the service
1366  * @param client the client that disconnected
1367  * @param internal_cls should be equal to @a c
1368  */
1369 static void
1370 client_disconnect_cb (void *cls,
1371                       struct GNUNET_SERVICE_Client *client,
1372                       void *internal_cls)
1373 {
1374   struct CadetClient *c = internal_cls;
1375
1376   GNUNET_assert (c->client == client);
1377   LOG (GNUNET_ERROR_TYPE_DEBUG,
1378        "%s is disconnecting.\n",
1379        GSC_2s (c));
1380   if (NULL != c->channels)
1381   {
1382     GNUNET_CONTAINER_multihashmap32_iterate (c->channels,
1383                                              &channel_destroy_iterator,
1384                                              c);
1385     GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap32_size (c->channels));
1386     GNUNET_CONTAINER_multihashmap32_destroy (c->channels);
1387   }
1388   if (NULL != c->ports)
1389   {
1390     GNUNET_CONTAINER_multihashmap_iterate (c->ports,
1391                                            &client_release_ports,
1392                                            c);
1393     GNUNET_CONTAINER_multihashmap_destroy (c->ports);
1394   }
1395   GNUNET_CONTAINER_DLL_remove (clients_head,
1396                                clients_tail,
1397                                c);
1398   GNUNET_STATISTICS_update (stats,
1399                             "# clients",
1400                             -1,
1401                             GNUNET_NO);
1402   GNUNET_free (c);
1403   if ( (NULL == clients_head) &&
1404        (GNUNET_YES == shutting_down) )
1405     shutdown_rest ();
1406 }
1407
1408
1409 /**
1410  * Setup CADET internals.
1411  *
1412  * @param cls closure
1413  * @param server the initialized server
1414  * @param c configuration to use
1415  */
1416 static void
1417 run (void *cls,
1418      const struct GNUNET_CONFIGURATION_Handle *c,
1419      struct GNUNET_SERVICE_Handle *service)
1420 {
1421   cfg = c;
1422   if (GNUNET_OK !=
1423       GNUNET_CONFIGURATION_get_value_number (c,
1424                                              "CADET",
1425                                              "RATCHET_MESSAGES",
1426                                              &ratchet_messages))
1427   {
1428     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1429                                "CADET",
1430                                "RATCHET_MESSAGES",
1431                                "needs to be a number");
1432     ratchet_messages = 64;
1433   }
1434   if (GNUNET_OK !=
1435       GNUNET_CONFIGURATION_get_value_time (c,
1436                                            "CADET",
1437                                            "RATCHET_TIME",
1438                                            &ratchet_time))
1439   {
1440     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1441                                "CADET",
1442                                "RATCHET_TIME",
1443                                "need delay value");
1444     ratchet_time = GNUNET_TIME_UNIT_HOURS;
1445   }
1446   if (GNUNET_OK !=
1447       GNUNET_CONFIGURATION_get_value_time (c,
1448                                            "CADET",
1449                                            "REFRESH_CONNECTION_TIME",
1450                                            &keepalive_period))
1451   {
1452     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1453                                "CADET",
1454                                "REFRESH_CONNECTION_TIME",
1455                                "need delay value");
1456     keepalive_period = GNUNET_TIME_UNIT_MINUTES;
1457   }
1458   if (GNUNET_OK !=
1459       GNUNET_CONFIGURATION_get_value_number (c,
1460                                              "CADET",
1461                                              "DROP_PERCENT",
1462                                              &drop_percent))
1463   {
1464     drop_percent = 0;
1465   }
1466   else
1467   {
1468     LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1469     LOG (GNUNET_ERROR_TYPE_WARNING, "Cadet is running with DROP enabled.\n");
1470     LOG (GNUNET_ERROR_TYPE_WARNING, "This is NOT a good idea!\n");
1471     LOG (GNUNET_ERROR_TYPE_WARNING, "Remove DROP_PERCENT from config file.\n");
1472     LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1473   }
1474   my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c);
1475   if (NULL == my_private_key)
1476   {
1477     GNUNET_break (0);
1478     GNUNET_SCHEDULER_shutdown ();
1479     return;
1480   }
1481   GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
1482                                       &my_full_id.public_key);
1483   stats = GNUNET_STATISTICS_create ("cadet",
1484                                     c);
1485   GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1486                                  NULL);
1487   ats_ch = GNUNET_ATS_connectivity_init (c);
1488   /* FIXME: optimize code to allow GNUNET_YES here! */
1489   open_ports = GNUNET_CONTAINER_multihashmap_create (16,
1490                                                      GNUNET_NO);
1491   loose_channels = GNUNET_CONTAINER_multihashmap_create (16,
1492                                                          GNUNET_NO);
1493   peers = GNUNET_CONTAINER_multipeermap_create (16,
1494                                                 GNUNET_YES);
1495   connections = GNUNET_CONTAINER_multishortmap_create (256,
1496                                                        GNUNET_YES);
1497   GCH_init (c);
1498   GCD_init (c);
1499   GCO_init (c);
1500   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1501               "CADET started for peer %s\n",
1502               GNUNET_i2s (&my_full_id));
1503
1504 }
1505
1506
1507 /**
1508  * Define "main" method using service macro.
1509  */
1510 GNUNET_SERVICE_MAIN
1511 ("cadet",
1512  GNUNET_SERVICE_OPTION_NONE,
1513  &run,
1514  &client_connect_cb,
1515  &client_disconnect_cb,
1516  NULL,
1517  GNUNET_MQ_hd_fixed_size (port_open,
1518                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN,
1519                           struct GNUNET_CADET_PortMessage,
1520                           NULL),
1521  GNUNET_MQ_hd_fixed_size (port_close,
1522                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE,
1523                           struct GNUNET_CADET_PortMessage,
1524                           NULL),
1525  GNUNET_MQ_hd_fixed_size (channel_create,
1526                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE,
1527                           struct GNUNET_CADET_LocalChannelCreateMessage,
1528                           NULL),
1529  GNUNET_MQ_hd_fixed_size (channel_destroy,
1530                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY,
1531                           struct GNUNET_CADET_LocalChannelDestroyMessage,
1532                           NULL),
1533  GNUNET_MQ_hd_var_size (local_data,
1534                         GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
1535                         struct GNUNET_CADET_LocalData,
1536                         NULL),
1537  GNUNET_MQ_hd_fixed_size (local_ack,
1538                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
1539                           struct GNUNET_CADET_LocalAck,
1540                           NULL),
1541  GNUNET_MQ_hd_fixed_size (get_peers,
1542                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
1543                           struct GNUNET_MessageHeader,
1544                           NULL),
1545  GNUNET_MQ_hd_fixed_size (show_peer,
1546                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER,
1547                           struct GNUNET_CADET_LocalInfo,
1548                           NULL),
1549  GNUNET_MQ_hd_fixed_size (info_tunnels,
1550                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
1551                           struct GNUNET_MessageHeader,
1552                           NULL),
1553  GNUNET_MQ_hd_fixed_size (info_tunnel,
1554                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL,
1555                           struct GNUNET_CADET_LocalInfo,
1556                           NULL),
1557  GNUNET_MQ_hd_fixed_size (info_dump,
1558                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP,
1559                           struct GNUNET_MessageHeader,
1560                           NULL),
1561  GNUNET_MQ_handler_end ());
1562
1563 /* end of gnunet-service-cadet-new.c */