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