- fix channel static functions
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh-enc.c
1 /*
2      This file is part of GNUnet.
3      (C) 2001-2013 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file mesh/gnunet-service-mesh-enc.c
23  * @brief GNUnet MESH service with encryption
24  * @author Bartlomiej Polot
25  *
26  *  FIXME in progress:
27  * - when sending in-order buffered data, wait for client ACKs
28  * - add signatures
29  * - add encryption
30  * - set connection IDs independently from tunnel, tunnel has no ID
31  *
32  * TODO:
33  * - relay corking down to core
34  * - set ttl relative to path length
35  * TODO END
36  *
37  * Dictionary:
38  * - peer: other mesh instance. If there is direct connection it's a neighbor.
39  * - tunnel: encrypted connection to a peer, neighbor or not.
40  * - channel: connection between two clients, on the same or different peers.
41  *            have properties like reliability.
42  * - path: series of directly connected peer from one peer to another.
43  * - connection: path which is being used in a tunnel.
44  */
45
46 #include "platform.h"
47 #include "gnunet_util_lib.h"
48 #include "mesh_enc.h"
49 #include "block_mesh.h"
50 #include "gnunet_statistics_service.h"
51
52 #include "gnunet-service-mesh_local.h"
53 #include "gnunet-service-mesh_channel.h"
54 #include "gnunet-service-mesh_connection.h"
55 #include "gnunet-service-mesh_dht.h"
56 #include "gnunet-service-mesh_peer.h"
57
58 #define MESH_BLOOM_SIZE         128
59
60
61 #define MESH_DEBUG_TIMING       __LINUX__ && GNUNET_NO
62
63
64 #if MESH_DEBUG_TIMING
65 #include <time.h>
66 double __sum;
67 uint64_t __count;
68 struct timespec __mesh_start;
69 struct timespec __mesh_end;
70 #define INTERVAL_START clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &(__mesh_start))
71 #define INTERVAL_END \
72 do {\
73   clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &(__mesh_end));\
74   double __diff = __mesh_end.tv_nsec - __mesh_start.tv_nsec;\
75   if (__diff < 0) __diff += 1000000000;\
76   __sum += __diff;\
77   __count++;\
78 } while (0)
79 #define INTERVAL_SHOW \
80 if (0 < __count)\
81   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "AVG process time: %f ns\n", __sum/__count)
82 #else
83 #define INTERVAL_START
84 #define INTERVAL_END
85 #define INTERVAL_SHOW
86 #endif
87
88 /**
89  * All the states a tunnel can be in.
90  */
91 enum MeshTunnelState
92 {
93     /**
94      * Uninitialized status, should never appear in operation.
95      */
96   MESH_TUNNEL_NEW,
97
98     /**
99      * Path to the peer not known yet
100      */
101   MESH_TUNNEL_SEARCHING,
102
103     /**
104      * Request sent, not yet answered.
105      */
106   MESH_TUNNEL_WAITING,
107
108     /**
109      * Peer connected and ready to accept data
110      */
111   MESH_TUNNEL_READY,
112
113     /**
114      * Peer connected previosly but not responding
115      */
116   MESH_TUNNEL_RECONNECTING
117 };
118
119
120
121 /******************************************************************************/
122 /************************      DATA STRUCTURES     ****************************/
123 /******************************************************************************/
124
125 /** FWD declaration */
126 struct MeshTunnel2;
127
128
129 /**
130  * Struct used to queue messages in a tunnel.
131  */
132 struct MeshTunnelQueue
133 {
134   /**
135    * DLL
136    */
137   struct MeshTunnelQueue *next;
138   struct MeshTunnelQueue *prev;
139
140   /**
141    * Channel.
142    */
143   struct MeshChannel *ch;
144
145   /**
146    * Message to send.
147    */
148   /* struct GNUNET_MessageHeader *msg; */
149 };
150
151
152 /**
153  * Struct containing all information regarding a tunnel to a peer.
154  */
155 struct MeshTunnel2
156 {
157     /**
158      * Endpoint of the tunnel.
159      */
160   struct MeshPeer *peer;
161
162     /**
163      * State of the tunnel.
164      */
165   enum MeshTunnelState state;
166
167   /**
168    * Local peer ephemeral private key
169    */
170   struct GNUNET_CRYPTO_EccPrivateKey *my_eph_key;
171
172   /**
173    * Local peer ephemeral public key
174    */
175   struct GNUNET_CRYPTO_EccPublicSignKey *my_eph;
176
177   /**
178    * Remote peer's public key.
179    */
180   struct GNUNET_CRYPTO_EccPublicSignKey *peers_eph;
181
182   /**
183    * Encryption ("our") key.
184    */
185   struct GNUNET_CRYPTO_SymmetricSessionKey e_key;
186
187   /**
188    * Decryption ("their") key.
189    */
190   struct GNUNET_CRYPTO_SymmetricSessionKey d_key;
191
192   /**
193    * Paths that are actively used to reach the destination peer.
194    */
195   struct MeshConnection *connection_head;
196   struct MeshConnection *connection_tail;
197
198   /**
199    * Next connection number.
200    */
201   uint32_t next_cid;
202
203   /**
204    * Channels inside this tunnel.
205    */
206   struct MeshChannel *channel_head;
207   struct MeshChannel *channel_tail;
208
209   /**
210    * Channel ID for the next created channel.
211    */
212   MESH_ChannelNumber next_chid;
213
214   /**
215    * Channel ID for the next incoming channel.
216    */
217   MESH_ChannelNumber next_local_chid;
218
219   /**
220    * Pending message count.
221    */
222   int pending_messages;
223
224   /**
225    * Destroy flag: if true, destroy on last message.
226    */
227   int destroy;
228
229   /**
230    * Queued messages, to transmit once tunnel gets connected.
231    */
232   struct MeshTunnelQueue *tq_head;
233   struct MeshTunnelQueue *tq_tail;
234 };
235
236
237
238 /******************************************************************************/
239 /************************      DEBUG FUNCTIONS     ****************************/
240 /******************************************************************************/
241
242 #if MESH_DEBUG
243 /**
244  * GNUNET_SCHEDULER_Task for printing a message after some operation is done
245  * @param cls string to print
246  * @param success  GNUNET_OK if the PUT was transmitted,
247  *                GNUNET_NO on timeout,
248  *                GNUNET_SYSERR on disconnect from service
249  *                after the PUT message was transmitted
250  *                (so we don't know if it was received or not)
251  */
252
253 #if 0
254 static void
255 mesh_debug (void *cls, int success)
256 {
257   char *s = cls;
258
259   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s (%d)\n", s, success);
260 }
261 #endif
262
263 #endif
264
265 /******************************************************************************/
266 /***********************      GLOBAL VARIABLES     ****************************/
267 /******************************************************************************/
268
269 /************************** Configuration parameters **************************/
270
271
272 /**
273  * Maximum time allowed to connect to a peer found by string.
274  */
275 static struct GNUNET_TIME_Relative connect_timeout;
276
277 /**
278  * Default TTL for payload packets.
279  */
280 static unsigned long long default_ttl;
281
282 /**
283  * Percentage of messages that will be dropped (for test purposes only).
284  */
285 static unsigned long long drop_percent;
286
287 /*************************** Static global variables **************************/
288
289 /**
290  * Handle to the statistics service.
291  */
292 static struct GNUNET_STATISTICS_Handle *stats;
293
294 /**
295  * Local peer own ID (memory efficient handle).
296  */
297 static GNUNET_PEER_Id myid;
298
299 /**
300  * Local peer own ID (full value).
301  */
302 static struct GNUNET_PeerIdentity my_full_id;
303
304 /**
305  * Own private key.
306  */
307 static struct GNUNET_CRYPTO_EccPrivateKey *my_private_key;
308
309
310 /******************************************************************************/
311 /***********************         DECLARATIONS        **************************/
312 /******************************************************************************/
313
314 /**
315  * Adds a path to the data structs of all the peers in the path
316  *
317  * @param p Path to process.
318  * @param confirmed Whether we know if the path works or not.
319  */
320 static void
321 path_add_to_peers (struct MeshPeerPath *p, int confirmed);
322
323
324 /**
325  * Change the tunnel state.
326  *
327  * @param t Tunnel whose state to change.
328  * @param state New state.
329  */
330 static void
331 tunnel_change_state (struct MeshTunnel2 *t, enum MeshTunnelState state);
332
333
334 /**
335  * Notify a tunnel that a connection has broken that affects at least
336  * some of its peers.
337  *
338  * @param t Tunnel affected.
339  * @param p1 Peer that got disconnected from p2.
340  * @param p2 Peer that got disconnected from p1.
341  *
342  * @return Short ID of the peer disconnected (either p1 or p2).
343  *         0 if the tunnel remained unaffected.
344  */
345 static GNUNET_PEER_Id
346 tunnel_notify_connection_broken (struct MeshTunnel2 *t,
347                                  GNUNET_PEER_Id p1, GNUNET_PEER_Id p2);
348
349 /**
350  * @brief Use the given path for the tunnel.
351  * Update the next and prev hops (and RCs).
352  * (Re)start the path refresh in case the tunnel is locally owned.
353  *
354  * @param t Tunnel to update.
355  * @param p Path to use.
356  *
357  * @return Connection created.
358  */
359 static struct MeshConnection *
360 tunnel_use_path (struct MeshTunnel2 *t, struct MeshPeerPath *p);
361
362 /**
363  * Tunnel is empty: destroy it.
364  *
365  * Notifies all participants (peers, cleints) about the destruction.
366  *
367  * @param t Tunnel to destroy.
368  */
369 static void
370 tunnel_destroy_empty (struct MeshTunnel2 *t);
371
372 /**
373  * Destroy the tunnel.
374  *
375  * This function does not generate any warning traffic to clients or peers.
376  *
377  * Tasks:
378  * Cancel messages belonging to this tunnel queued to neighbors.
379  * Free any allocated resources linked to the tunnel.
380  *
381  * @param t The tunnel to destroy.
382  */
383 static void
384 tunnel_destroy (struct MeshTunnel2 *t);
385
386
387 /**
388  * Demultiplex by message type and call appropriate handler for a message
389  * towards a channel of a local tunnel.
390  *
391  * @param t Tunnel this message came on.
392  * @param msgh Message header.
393  * @param fwd Is this message fwd?
394  */
395 static void
396 handle_decrypted (struct MeshTunnel2 *t,
397                   const struct GNUNET_MessageHeader *msgh,
398                   int fwd);
399
400
401 /**
402  * Dummy function to separate declarations from definitions in function list.
403  */
404 void
405 __mesh_divider______________________________________________________________();
406
407
408 /**
409  * Get string description for tunnel state.
410  *
411  * @param s Tunnel state.
412  *
413  * @return String representation.
414  */
415 static const char *
416 GNUNET_MESH_DEBUG_TS2S (enum MeshTunnelState s)
417 {
418   static char buf[128];
419
420   switch (s)
421   {
422     case MESH_TUNNEL_NEW:
423       return "MESH_TUNNEL_NEW";
424     case MESH_TUNNEL_SEARCHING:
425       return "MESH_TUNNEL_SEARCHING";
426     case MESH_TUNNEL_WAITING:
427       return "MESH_TUNNEL_WAITING";
428     case MESH_TUNNEL_READY:
429       return "MESH_TUNNEL_READY";
430     case MESH_TUNNEL_RECONNECTING:
431       return "MESH_TUNNEL_RECONNECTING";
432
433     default:
434       sprintf (buf, "%u (UNKNOWN STATE)", s);
435       return buf;
436   }
437 }
438
439
440
441
442 /******************************************************************************/
443 /******************      GENERAL HELPER FUNCTIONS      ************************/
444 /******************************************************************************/
445
446
447 /**
448  * Get the static string for a peer ID.
449  *
450  * @param peer Peer.
451  *
452  * @return Static string for it's ID.
453  */
454 static const char *
455 peer2s (const struct MeshPeer *peer)
456 {
457   if (NULL == peer)
458     return "(NULL)";
459   return GNUNET_i2s (GNUNET_PEER_resolve2 (peer->id));
460 }
461
462
463
464 /**
465  * Count established (ready) connections of a tunnel.
466  *
467  * @param t Tunnel on which to send the message.
468  *
469  * @return Number of connections.
470  */
471 static unsigned int
472 tunnel_count_connections (struct MeshTunnel2 *t)
473 {
474   struct MeshConnection *c;
475   unsigned int i;
476
477   for (c = t->connection_head, i = 0; NULL != c; c = c->next, i++);
478
479   return i;
480 }
481
482
483 /**
484  * Pick a connection on which send the next data message.
485  *
486  * @param t Tunnel on which to send the message.
487  * @param fwd Is this a fwd message?
488  *
489  * @return The connection on which to send the next message.
490  */
491 static struct MeshConnection *
492 tunnel_get_connection (struct MeshTunnel2 *t, int fwd)
493 {
494   struct MeshConnection *c;
495   struct MeshConnection *best;
496   struct MeshFlowControl *fc;
497   unsigned int lowest_q;
498
499   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n",
500               peer2s (t->peer));
501   best = NULL;
502   lowest_q = UINT_MAX;
503   for (c = t->connection_head; NULL != c; c = c->next)
504   {
505     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  connection %s: %u\n",
506                 GNUNET_h2s (&c->id), c->state);
507     if (MESH_CONNECTION_READY == c->state)
508     {
509       fc = fwd ? &c->fwd_fc : &c->bck_fc;
510       if (NULL == fc)
511       {
512         GNUNET_break (0);
513         continue;
514       }
515       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    q_n %u, \n", fc->queue_n);
516       if (fc->queue_n < lowest_q)
517       {
518         best = c;
519         lowest_q = fc->queue_n;
520       }
521     }
522   }
523   return best;
524 }
525
526
527
528
529 /**
530  * Get the total buffer space for a tunnel.
531  *
532  * @param t Tunnel.
533  * @param fwd Is this for FWD traffic?
534  *
535  * @return Buffer space offered by all connections in the tunnel.
536  */
537 static unsigned int
538 tunnel_get_buffer (struct MeshTunnel2 *t, int fwd)
539 {
540   struct MeshConnection *c;
541   struct MeshFlowControl *fc;
542   unsigned int buffer;
543
544   c = t->connection_head;
545   buffer = 0;
546
547   /* If terminal, return biggest channel buffer */
548   if (NULL == c || GMC_is_terminal (c, fwd))
549   {
550     struct MeshChannel *ch;
551     unsigned int ch_buf;
552
553     if (NULL == t->channel_head)
554       return 64;
555
556     for (ch = t->channel_head; NULL != ch; ch = ch->next)
557     {
558       ch_buf = channel_get_buffer (ch, fwd);
559       if (ch_buf > buffer)
560         buffer = ch_buf;
561     }
562     return buffer;
563   }
564
565   /* If not terminal, return sum of connection buffers */
566   while (NULL != c)
567   {
568     if (c->state != MESH_CONNECTION_READY)
569     {
570       c = c->next;
571       continue;
572     }
573
574     fc = fwd ? &c->fwd_fc : &c->bck_fc;
575     buffer += fc->queue_max - fc->queue_n;
576     c = c->next;
577   }
578
579   return buffer;
580 }
581
582
583 /**
584  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
585  * Encrypt data with the tunnel key.
586  *
587  * @param t Tunnel whose key to use.
588  * @param dst Destination for the encrypted data.
589  * @param src Source of the plaintext.
590  * @param size Size of the plaintext.
591  * @param iv Initialization Vector to use.
592  * @param fwd Is this a fwd message?
593  */
594 static void
595 tunnel_encrypt (struct MeshTunnel2 *t,
596                 void *dst, const void *src,
597                 size_t size, uint64_t iv, int fwd)
598 {
599   memcpy (dst, src, size);
600 }
601
602
603 /**
604  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
605  * Decrypt data with the tunnel key.
606  *
607  * @param t Tunnel whose key to use.
608  * @param dst Destination for the plaintext.
609  * @param src Source of the encrypted data.
610  * @param size Size of the encrypted data.
611  * @param iv Initialization Vector to use.
612  * @param fwd Is this a fwd message?
613  */
614 static void
615 tunnel_decrypt (struct MeshTunnel2 *t,
616                 void *dst, const void *src,
617                 size_t size, uint64_t iv, int fwd)
618 {
619   memcpy (dst, src, size);
620 }
621
622
623 /**
624  * Sends an already built message on a tunnel, choosing the best connection.
625  *
626  * @param message Message to send. Function modifies it.
627  * @param t Tunnel on which this message is transmitted.
628  * @param ch Channel on which this message is transmitted.
629  * @param fwd Is this a fwd message?
630  */
631 static void
632 send_prebuilt_message_tunnel (struct GNUNET_MESH_Encrypted *msg,
633                               struct MeshTunnel2 *t,
634                               struct MeshChannel *ch,
635                               int fwd)
636 {
637   struct MeshConnection *c;
638   uint16_t type;
639
640   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n",
641               peer2s (t->peer));
642   c = tunnel_get_connection (t, fwd);
643   if (NULL == c)
644   {
645     GNUNET_break (GNUNET_YES == t->destroy);
646     return;
647   }
648   type = ntohs (msg->header.type);
649   switch (type)
650   {
651     case GNUNET_MESSAGE_TYPE_MESH_FWD:
652     case GNUNET_MESSAGE_TYPE_MESH_BCK:
653     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
654     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
655       msg->cid = c->id;
656       msg->ttl = htonl (default_ttl);
657       break;
658     default:
659       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "unkown type %s\n",
660                   GNUNET_MESH_DEBUG_M2S (type));
661       GNUNET_break (0);
662   }
663   msg->reserved = 0;
664
665   send_prebuilt_message_connection (&msg->header, c, ch, fwd);
666 }
667
668
669
670 /**
671  * Sends a CREATE CONNECTION message for a path to a peer.
672  * Changes the connection and tunnel states if necessary.
673  *
674  * @param connection Connection to create.
675  */
676 static void
677 send_connection_create (struct MeshConnection *connection)
678 {
679   struct MeshTunnel2 *t;
680
681   t = connection->t;
682   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send connection create\n");
683   queue_add (NULL,
684              GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE,
685              sizeof (struct GNUNET_MESH_ConnectionCreate) +
686                 (connection->path->length *
687                  sizeof (struct GNUNET_PeerIdentity)),
688              connection,
689              NULL,
690              GNUNET_YES);
691   if (NULL != t &&
692       (MESH_TUNNEL_SEARCHING == t->state || MESH_TUNNEL_NEW == t->state))
693     tunnel_change_state (t, MESH_TUNNEL_WAITING);
694   if (MESH_CONNECTION_NEW == connection->state)
695     connection_change_state (connection, MESH_CONNECTION_SENT);
696 }
697
698
699 /**
700  * Sends a CONNECTION ACK message in reponse to a received CONNECTION_CREATE
701  * directed to us.
702  *
703  * @param connection Connection to confirm.
704  * @param fwd Is this a fwd ACK? (First is bck (SYNACK), second is fwd (ACK))
705  */
706 static void
707 send_connection_ack (struct MeshConnection *connection, int fwd)
708 {
709   struct MeshTunnel2 *t;
710
711   t = connection->t;
712   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send connection ack\n");
713   queue_add (NULL,
714              GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK,
715              sizeof (struct GNUNET_MESH_ConnectionACK),
716              connection,
717              NULL,
718              fwd);
719   if (MESH_TUNNEL_NEW == t->state)
720     tunnel_change_state (t, MESH_TUNNEL_WAITING);
721   if (MESH_CONNECTION_READY != connection->state)
722     connection_change_state (connection, MESH_CONNECTION_SENT);
723 }
724
725
726 /**
727   * Core callback to write a pre-constructed data packet to core buffer
728   *
729   * @param cls Closure (MeshTransmissionDescriptor with data in "data" member).
730   * @param size Number of bytes available in buf.
731   * @param buf Where the to write the message.
732   *
733   * @return number of bytes written to buf
734   */
735 static size_t
736 send_core_data_raw (void *cls, size_t size, void *buf)
737 {
738   struct GNUNET_MessageHeader *msg = cls;
739   size_t total_size;
740
741   GNUNET_assert (NULL != msg);
742   total_size = ntohs (msg->size);
743
744   if (total_size > size)
745   {
746     GNUNET_break (0);
747     return 0;
748   }
749   memcpy (buf, msg, total_size);
750   GNUNET_free (cls);
751   return total_size;
752 }
753
754
755 /**
756  * Function to send a create connection message to a peer.
757  *
758  * @param c Connection to create.
759  * @param size number of bytes available in buf
760  * @param buf where the callee should write the message
761  * @return number of bytes written to buf
762  */
763 static size_t
764 send_core_connection_create (struct MeshConnection *c, size_t size, void *buf)
765 {
766   struct GNUNET_MESH_ConnectionCreate *msg;
767   struct GNUNET_PeerIdentity *peer_ptr;
768   struct MeshPeerPath *p = c->path;
769   size_t size_needed;
770   int i;
771
772   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending CONNECTION CREATE...\n");
773   size_needed =
774       sizeof (struct GNUNET_MESH_ConnectionCreate) +
775       p->length * sizeof (struct GNUNET_PeerIdentity);
776
777   if (size < size_needed || NULL == buf)
778   {
779     GNUNET_break (0);
780     return 0;
781   }
782   msg = (struct GNUNET_MESH_ConnectionCreate *) buf;
783   msg->header.size = htons (size_needed);
784   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE);
785   msg->cid = c->id;
786
787   peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1];
788   for (i = 0; i < p->length; i++)
789   {
790     GNUNET_PEER_resolve (p->peers[i], peer_ptr++);
791   }
792
793   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
794               "CONNECTION CREATE (%u bytes long) sent!\n", size_needed);
795   return size_needed;
796 }
797
798
799 /**
800  * Creates a path ack message in buf and frees all unused resources.
801  *
802  * @param c Connection to send an ACK on.
803  * @param size number of bytes available in buf
804  * @param buf where the callee should write the message
805  *
806  * @return number of bytes written to buf
807  */
808 static size_t
809 send_core_connection_ack (struct MeshConnection *c, size_t size, void *buf)
810 {
811   struct GNUNET_MESH_ConnectionACK *msg = buf;
812   struct MeshTunnel2 *t = c->t;
813
814   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending CONNECTION ACK...\n");
815   GNUNET_assert (NULL != t);
816   if (sizeof (struct GNUNET_MESH_ConnectionACK) > size)
817   {
818     GNUNET_break (0);
819     return 0;
820   }
821   msg->header.size = htons (sizeof (struct GNUNET_MESH_ConnectionACK));
822   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK);
823   msg->cid = c->id;
824   msg->reserved = 0;
825
826   /* TODO add signature */
827
828   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONNECTION ACK sent!\n");
829   return sizeof (struct GNUNET_MESH_ConnectionACK);
830 }
831
832
833
834 /**
835  * Adds a path to the peer_infos of all the peers in the path
836  *
837  * @param p Path to process.
838  * @param confirmed Whether we know if the path works or not.
839  */
840 static void
841 path_add_to_peers (struct MeshPeerPath *p, int confirmed)
842 {
843   unsigned int i;
844
845   /* TODO: invert and add */
846   for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ;
847   for (i++; i < p->length; i++)
848   {
849     struct MeshPeer *aux;
850     struct MeshPeerPath *copy;
851
852     aux = peer_get_short (p->peers[i]);
853     copy = path_duplicate (p);
854     copy->length = i + 1;
855     peer_add_path (aux, copy, p->length < 3 ? GNUNET_NO : confirmed);
856   }
857 }
858
859
860 #if 0
861 static void
862 fc_debug (struct MeshFlowControl *fc)
863 {
864   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    IN: %u/%u\n",
865               fc->last_pid_recv, fc->last_ack_sent);
866   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    OUT: %u/%u\n",
867               fc->last_pid_sent, fc->last_ack_recv);
868   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    QUEUE: %u/%u\n",
869               fc->queue_n, fc->queue_max);
870 }
871
872 static void
873 connection_debug (struct MeshConnection *c)
874 {
875   if (NULL == c)
876   {
877     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*** DEBUG NULL CONNECTION ***\n");
878     return;
879   }
880   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection %s:%X\n",
881               peer2s (c->t->peer), GNUNET_h2s (&c->id));
882   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  state: %u, pending msgs: %u\n",
883               c->state, c->pending_messages);
884   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  FWD FC\n");
885   fc_debug (&c->fwd_fc);
886   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  BCK FC\n");
887   fc_debug (&c->bck_fc);
888 }
889
890 #endif
891
892
893 /**
894  * Change the tunnel state.
895  *
896  * @param t Tunnel whose state to change.
897  * @param state New state.
898  */
899 static void
900 tunnel_change_state (struct MeshTunnel2* t, enum MeshTunnelState state)
901 {
902   if (NULL == t)
903     return;
904   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
905               "Tunnel %s state was %s\n",
906               peer2s (t->peer),
907               GNUNET_MESH_DEBUG_TS2S (t->state));
908   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
909               "Tunnel %s state is now %s\n",
910               peer2s (t->peer),
911               GNUNET_MESH_DEBUG_TS2S (state));
912   t->state = state;
913 }
914
915
916 /**
917  * Send all cached messages that we can, tunnel is online.
918  *
919  * @param t Tunnel that holds the messages.
920  * @param fwd Is this fwd?
921  */
922 static void
923 tunnel_send_queued_data (struct MeshTunnel2 *t, int fwd)
924 {
925   struct MeshTunnelQueue *tq;
926   struct MeshTunnelQueue *next;
927   unsigned int room;
928
929   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
930               "tunnel_send_queued_data on tunnel %s\n",
931               peer2s (t->peer));
932   room = tunnel_get_buffer (t, fwd);
933   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  buffer space: %u\n", room);
934   for (tq = t->tq_head; NULL != tq && room > 0; tq = next)
935   {
936     next = tq->next;
937     room--;
938     GNUNET_CONTAINER_DLL_remove (t->tq_head, t->tq_tail, tq);
939     send_prebuilt_message_channel ((struct GNUNET_MessageHeader *) &tq[1],
940                                    tq->ch, fwd);
941
942     GNUNET_free (tq);
943   }
944 }
945
946
947 /**
948  * Cache a message to be sent once tunnel is online.
949  *
950  * @param t Tunnel to hold the message.
951  * @param ch Channel the message is about.
952  * @param msg Message itself (copy will be made).
953  * @param fwd Is this fwd?
954  */
955 static void
956 tunnel_queue_data (struct MeshTunnel2 *t,
957                    struct MeshChannel *ch,
958                    struct GNUNET_MessageHeader *msg,
959                    int fwd)
960 {
961   struct MeshTunnelQueue *tq;
962   uint16_t size = ntohs (msg->size);
963
964   tq = GNUNET_malloc (sizeof (struct MeshTunnelQueue) + size);
965
966   tq->ch = ch;
967   memcpy (&tq[1], msg, size);
968   GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tq);
969
970   if (MESH_TUNNEL_READY == t->state)
971     tunnel_send_queued_data (t, fwd);
972 }
973
974
975
976
977
978 static struct MeshConnection *
979 tunnel_use_path (struct MeshTunnel2 *t, struct MeshPeerPath *p)
980 {
981   struct MeshConnection *c;
982   struct GNUNET_HashCode cid;
983   struct MeshPeer *peer;
984   unsigned int own_pos;
985
986   if (NULL == t || NULL == p)
987   {
988     GNUNET_break (0);
989     return NULL;
990   }
991
992   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, &cid);
993
994   c = connection_new (&cid);
995   c->t = t;
996   GNUNET_CONTAINER_DLL_insert (t->connection_head, t->connection_tail, c);
997   for (own_pos = 0; own_pos < p->length; own_pos++)
998   {
999     if (p->peers[own_pos] == myid)
1000       break;
1001   }
1002   if (own_pos > p->length - 1)
1003   {
1004     GNUNET_break (0);
1005     connection_destroy (c);
1006     return NULL;
1007   }
1008   c->own_pos = own_pos;
1009   c->path = p;
1010
1011   if (0 == own_pos)
1012   {
1013     c->fwd_maintenance_task =
1014         GNUNET_SCHEDULER_add_delayed (refresh_connection_time,
1015                                       &connection_fwd_keepalive, c);
1016   }
1017
1018   peer = connection_get_next_hop (c);
1019   if (NULL == peer->connections)
1020   {
1021     connection_destroy (c);
1022     return NULL;
1023   }
1024   GNUNET_CONTAINER_multihashmap_put (peer->connections, &c->id, c,
1025                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1026   peer = connection_get_prev_hop (c);
1027   if (NULL == peer->connections)
1028   {
1029     connection_destroy (c);
1030     return NULL;
1031   }
1032   GNUNET_CONTAINER_multihashmap_put (peer->connections, &c->id, c,
1033                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1034   return c;
1035 }
1036
1037
1038 /**
1039  * Notifies a tunnel that a connection has broken that affects at least
1040  * some of its peers. Sends a notification towards the root of the tree.
1041  * In case the peer is the owner of the tree, notifies the client that owns
1042  * the tunnel and tries to reconnect.
1043  *
1044  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
1045  *
1046  * @param t Tunnel affected.
1047  * @param p1 Peer that got disconnected from p2.
1048  * @param p2 Peer that got disconnected from p1.
1049  *
1050  * @return Short ID of the peer disconnected (either p1 or p2).
1051  *         0 if the tunnel remained unaffected.
1052  */
1053 static GNUNET_PEER_Id
1054 tunnel_notify_connection_broken (struct MeshTunnel2* t,
1055                                  GNUNET_PEER_Id p1, GNUNET_PEER_Id p2)
1056 {
1057 //   if (myid != p1 && myid != p2) FIXME
1058 //   {
1059 //     return;
1060 //   }
1061 //
1062 //   if (tree_get_predecessor (t->tree) != 0)
1063 //   {
1064 //     /* We are the peer still connected, notify owner of the disconnection. */
1065 //     struct GNUNET_MESH_PathBroken msg;
1066 //     struct GNUNET_PeerIdentity neighbor;
1067 //
1068 //     msg.header.size = htons (sizeof (msg));
1069 //     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
1070 //     GNUNET_PEER_resolve (t->id.oid, &msg.oid);
1071 //     msg.tid = htonl (t->id.tid);
1072 //     msg.peer1 = my_full_id;
1073 //     GNUNET_PEER_resolve (pid, &msg.peer2);
1074 //     GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
1075 //     send_prebuilt_message (&msg.header, &neighbor, t);
1076 //   }
1077   return 0;
1078 }
1079
1080
1081
1082
1083 /**
1084  * Send an ACK on the appropriate connection/channel, depending on
1085  * the direction and the position of the peer.
1086  *
1087  * @param c Which connection to send the hop-by-hop ACK.
1088  * @param ch Channel, if any.
1089  * @param fwd Is this a fwd ACK? (will go dest->root)
1090  */
1091 static void
1092 send_ack (struct MeshConnection *c, struct MeshChannel *ch, int fwd)
1093 {
1094   unsigned int buffer;
1095
1096   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1097               "send ack %s on %p %p\n",
1098               fwd ? "FWD" : "BCK", c, ch);
1099   if (NULL == c || GMC_is_terminal (c, fwd))
1100   {
1101     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  getting from all connections\n");
1102     buffer = tunnel_get_buffer (NULL == c ? ch->t : c->t, fwd);
1103   }
1104   else
1105   {
1106     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  getting from one connection\n");
1107     buffer = connection_get_buffer (c, fwd);
1108   }
1109   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  buffer available: %u\n", buffer);
1110
1111   if ( (NULL != ch && channel_is_origin (ch, fwd)) ||
1112        (NULL != c && connection_is_origin (c, fwd)) )
1113   {
1114     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  sending on channel...\n");
1115     if (0 < buffer)
1116     {
1117       GNUNET_assert (NULL != ch);
1118       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  really sending!\n");
1119       send_local_ack (ch, fwd);
1120     }
1121   }
1122   else if (NULL == c)
1123   {
1124     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  sending on all connections\n");
1125     GNUNET_assert (NULL != ch);
1126     channel_send_connections_ack (ch, buffer, fwd);
1127   }
1128   else
1129   {
1130     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  sending on connection\n");
1131     connection_send_ack (c, buffer, fwd);
1132   }
1133 }
1134
1135
1136
1137
1138 /**
1139  * Confirm we got a channel create.
1140  *
1141  * @param ch The channel to confirm.
1142  * @param fwd Should we send the ACK fwd?
1143  */
1144 static void
1145 channel_send_ack (struct MeshChannel *ch, int fwd)
1146 {
1147   struct GNUNET_MESH_ChannelManage msg;
1148
1149   msg.header.size = htons (sizeof (msg));
1150   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK);
1151   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1152               "  sending channel %s ack for channel %s:%X\n",
1153               fwd ? "FWD" : "BCK", peer2s (ch->t->peer),
1154               ch->gid);
1155
1156   msg.chid = htonl (ch->gid);
1157   send_prebuilt_message_channel (&msg.header, ch, !fwd);
1158 }
1159
1160
1161 /**
1162  * Send a message to all clients (local and remote) of this channel
1163  * notifying that the channel is no longer valid.
1164  *
1165  * If some peer or client should not receive the message,
1166  * should be zero'ed out before calling this function.
1167  *
1168  * @param ch The channel whose clients to notify.
1169  */
1170 static void
1171 channel_send_destroy (struct MeshChannel *ch)
1172 {
1173   struct GNUNET_MESH_ChannelManage msg;
1174
1175   msg.header.size = htons (sizeof (msg));
1176   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY);
1177   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1178               "  sending channel destroy for channel %s:%X\n",
1179               peer2s (ch->t->peer),
1180               ch->gid);
1181
1182   if (channel_is_terminal (ch, GNUNET_NO))
1183   {
1184     if (NULL != ch->root && GNUNET_NO == ch->root->shutting_down)
1185     {
1186       msg.chid = htonl (ch->lid_root);
1187       send_local_channel_destroy (ch, GNUNET_NO);
1188     }
1189   }
1190   else
1191   {
1192     msg.chid = htonl (ch->gid);
1193     send_prebuilt_message_channel (&msg.header, ch, GNUNET_NO);
1194   }
1195
1196   if (channel_is_terminal (ch, GNUNET_YES))
1197   {
1198     if (NULL != ch->dest && GNUNET_NO == ch->dest->shutting_down)
1199     {
1200       msg.chid = htonl (ch->lid_dest);
1201       send_local_channel_destroy (ch, GNUNET_YES);
1202     }
1203   }
1204   else
1205   {
1206     msg.chid = htonl (ch->gid);
1207     send_prebuilt_message_channel (&msg.header, ch, GNUNET_YES);
1208   }
1209 }
1210
1211
1212 /**
1213  * Create a tunnel.
1214  */
1215 static struct MeshTunnel2 *
1216 tunnel_new (void)
1217 {
1218   struct MeshTunnel2 *t;
1219
1220   t = GNUNET_new (struct MeshTunnel2);
1221   t->next_chid = 0;
1222   t->next_local_chid = GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
1223 //   if (GNUNET_OK !=
1224 //       GNUNET_CONTAINER_multihashmap_put (tunnels, tid, t,
1225 //                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
1226 //   {
1227 //     GNUNET_break (0);
1228 //     tunnel_destroy (t);
1229 //     return NULL;
1230 //   }
1231
1232 //   char salt[] = "salt";
1233 //   GNUNET_CRYPTO_kdf (&t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1234 //                      salt, sizeof (salt),
1235 //                      &t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1236 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
1237 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
1238 //                      NULL);
1239 //   GNUNET_CRYPTO_kdf (&t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1240 //                      salt, sizeof (salt),
1241 //                      &t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1242 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
1243 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
1244 //                      NULL);
1245
1246   return t;
1247 }
1248
1249
1250 /**
1251  * Add a connection to a tunnel.
1252  *
1253  * @param t Tunnel.
1254  * @param c Connection.
1255  */
1256 static void
1257 tunnel_add_connection (struct MeshTunnel2 *t, struct MeshConnection *c)
1258 {
1259   struct MeshConnection *aux;
1260   c->t = t;
1261   for (aux = t->connection_head; aux != NULL; aux = aux->next)
1262     if (aux == c)
1263       return;
1264   GNUNET_CONTAINER_DLL_insert_tail (t->connection_head, t->connection_tail, c);
1265 }
1266
1267
1268
1269 static void
1270 tunnel_destroy (struct MeshTunnel2 *t)
1271 {
1272   struct MeshConnection *c;
1273   struct MeshConnection *next;
1274
1275   if (NULL == t)
1276     return;
1277
1278   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n",
1279               peer2s (t->peer));
1280
1281 //   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &t->id, t))
1282 //     GNUNET_break (0);
1283
1284   for (c = t->connection_head; NULL != c; c = next)
1285   {
1286     next = c->next;
1287     connection_destroy (c);
1288   }
1289
1290   GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
1291   t->peer->tunnel = NULL;
1292
1293   GNUNET_free (t);
1294 }
1295
1296
1297 /**
1298  * Tunnel is empty: destroy it.
1299  *
1300  * Notifies all connections about the destruction.
1301  *
1302  * @param t Tunnel to destroy.
1303  */
1304 static void
1305 tunnel_destroy_empty (struct MeshTunnel2 *t)
1306 {
1307   struct MeshConnection *c;
1308
1309   for (c = t->connection_head; NULL != c; c = c->next)
1310   {
1311     if (GNUNET_NO == c->destroy)
1312       connection_send_destroy (c);
1313   }
1314
1315   if (0 == t->pending_messages)
1316     tunnel_destroy (t);
1317   else
1318     t->destroy = GNUNET_YES;
1319 }
1320
1321
1322 /**
1323  * Destroy tunnel if empty (no more channels).
1324  *
1325  * @param t Tunnel to destroy if empty.
1326  */
1327 static void
1328 tunnel_destroy_if_empty (struct MeshTunnel2 *t)
1329 {
1330   if (NULL != t->channel_head)
1331     return;
1332
1333   tunnel_destroy_empty (t);
1334 }
1335
1336
1337 /******************************************************************************/
1338 /****************      MESH NETWORK HANDLER HELPERS     ***********************/
1339 /******************************************************************************/
1340
1341
1342
1343
1344
1345
1346 /******************************************************************************/
1347 /********************      MESH NETWORK HANDLERS     **************************/
1348 /******************************************************************************/
1349
1350 static void
1351 handle_decrypted (struct MeshTunnel2 *t,
1352                   const struct GNUNET_MessageHeader *msgh,
1353                   int fwd)
1354 {
1355   switch (ntohs (msgh->type))
1356   {
1357     case GNUNET_MESSAGE_TYPE_MESH_DATA:
1358       /* Don't send hop ACK, wait for client to ACK */
1359       handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd);
1360       break;
1361
1362     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
1363       handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd);
1364       break;
1365
1366     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
1367       handle_channel_create (t,
1368                              (struct GNUNET_MESH_ChannelCreate *) msgh,
1369                              fwd);
1370       break;
1371
1372     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
1373       handle_channel_ack (t,
1374                           (struct GNUNET_MESH_ChannelManage *) msgh,
1375                           fwd);
1376       break;
1377
1378     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
1379       handle_channel_destroy (t,
1380                               (struct GNUNET_MESH_ChannelManage *) msgh,
1381                               fwd);
1382       break;
1383
1384     default:
1385       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1386                   "end-to-end message not known (%u)\n",
1387                   ntohs (msgh->type));
1388   }
1389 }
1390
1391
1392 /**
1393  * Function to process paths received for a new peer addition. The recorded
1394  * paths form the initial tunnel, which can be optimized later.
1395  * Called on each result obtained for the DHT search.
1396  *
1397  * @param cls closure
1398  * @param path
1399  */
1400 static void
1401 search_handler (void *cls, struct MeshPeerPath *path)
1402 {
1403 //   struct MeshConnection *c;
1404   unsigned int connection_count;
1405
1406   path_add_to_peers (path, GNUNET_NO);
1407
1408   /* Count connections */
1409   connection_count = GMC_count (peer->tunnel->connection_head);
1410
1411   /* If we already have 3 (or more (?!)) connections, it's enough */
1412   if (3 <= connection_count)
1413     return;
1414
1415   if (peer->tunnel->state == MESH_TUNNEL_SEARCHING)
1416   {
1417     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... connect!\n");
1418     peer_connect (peer);
1419   }
1420   return;
1421 }
1422
1423
1424 /******************************************************************************/
1425 /************************      MAIN FUNCTIONS      ****************************/
1426 /******************************************************************************/
1427
1428
1429
1430
1431 /**
1432  * Task run during shutdown.
1433  *
1434  * @param cls unused
1435  * @param tc unused
1436  */
1437 static void
1438 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1439 {
1440   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutting down\n");
1441
1442   GML_shutdown ();
1443   GMD_shutdown ();
1444   GMP_shutdown ();
1445   GMC_shutdown ();
1446
1447   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n");
1448 }
1449
1450
1451 /**
1452  * Process mesh requests.
1453  *
1454  * @param cls closure
1455  * @param server the initialized server
1456  * @param c configuration to use
1457  */
1458 static void
1459 run (void *cls, struct GNUNET_SERVER_Handle *server,
1460      const struct GNUNET_CONFIGURATION_Handle *c)
1461 {
1462   struct GNUNET_CRYPTO_EccPrivateKey *pk;
1463
1464   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n");
1465
1466   if (GNUNET_OK !=
1467       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "CONNECT_TIMEOUT",
1468                                            &connect_timeout))
1469   {
1470     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
1471                                "MESH", "CONNECT_TIMEOUT", "MISSING");
1472     GNUNET_SCHEDULER_shutdown ();
1473     return;
1474   }
1475
1476   if (GNUNET_OK !=
1477       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL",
1478                                              &default_ttl))
1479   {
1480     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1481                                "MESH", "DEFAULT_TTL", "USING DEFAULT");
1482     default_ttl = 64;
1483   }
1484
1485   if (GNUNET_OK !=
1486       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DROP_PERCENT",
1487                                              &drop_percent))
1488   {
1489     drop_percent = 0;
1490   }
1491   else
1492   {
1493     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1494                 "\n***************************************\n"
1495                 "Mesh is running with drop mode enabled.\n"
1496                 "This is NOT a good idea!\n"
1497                 "Remove the DROP_PERCENT option from your configuration.\n"
1498                 "***************************************\n");
1499   }
1500
1501
1502   stats = GNUNET_STATISTICS_create ("mesh", c);
1503
1504   /* Scheduled the task to clean up when shutdown is called */
1505   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
1506                                 NULL);
1507   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "reading key\n");
1508   pk = GNUNET_CRYPTO_ecc_key_create_from_configuration (c);
1509   GNUNET_assert (NULL != pk);
1510   my_private_key = pk;
1511   GNUNET_CRYPTO_ecc_key_get_public_for_signature (my_private_key,
1512                                                   &my_full_id.public_key);
1513   myid = GNUNET_PEER_intern (&my_full_id);
1514   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1515               "Mesh for peer [%s] starting\n",
1516               GNUNET_i2s(&my_full_id));
1517
1518   GML_init (server);    /* Local clients */
1519   GMC_init (c);         /* Connections */
1520   GMP_init (c);         /* Peers */
1521   GMD_init (c, &my_full_id);         /* DHT */
1522
1523   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh service running\n");
1524 }
1525
1526
1527 /**
1528  * The main function for the mesh service.
1529  *
1530  * @param argc number of arguments from the command line
1531  * @param argv command line arguments
1532  * @return 0 ok, 1 on error
1533  */
1534 int
1535 main (int argc, char *const *argv)
1536 {
1537   int ret;
1538   int r;
1539
1540   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main()\n");
1541   r = GNUNET_SERVICE_run (argc, argv, "mesh", GNUNET_SERVICE_OPTION_NONE, &run,
1542                           NULL);
1543   ret = (GNUNET_OK == r) ? 0 : 1;
1544   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main() END\n");
1545
1546   INTERVAL_SHOW;
1547
1548   return ret;
1549 }