-remove trailing whitespace
[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  * Function to process paths received for a new peer addition. The recorded
316  * paths form the initial tunnel, which can be optimized later.
317  * Called on each result obtained for the DHT search.
318  *
319  * @param cls closure
320  * @param exp when will this value expire
321  * @param key key of the result
322  * @param type type of the result
323  * @param size number of bytes in data
324  * @param data pointer to the result data
325  */
326 static void
327 dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
328                     const struct GNUNET_HashCode * key,
329                     const struct GNUNET_PeerIdentity *get_path,
330                     unsigned int get_path_length,
331                     const struct GNUNET_PeerIdentity *put_path,
332                     unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
333                     size_t size, const void *data);
334
335
336 /**
337  * Retrieve the MeshPeer stucture associated with the peer, create one
338  * and insert it in the appropriate structures if the peer is not known yet.
339  *
340  * @param peer Full identity of the peer.
341  *
342  * @return Existing or newly created peer info.
343  */
344 static struct MeshPeer *
345 peer_get (const struct GNUNET_PeerIdentity *peer);
346
347
348 /**
349  * Retrieve the MeshPeer stucture associated with the peer, create one
350  * and insert it in the appropriate structures if the peer is not known yet.
351  *
352  * @param peer Short identity of the peer.
353  *
354  * @return Existing or newly created peer info.
355  */
356 static struct MeshPeer *
357 peer_get_short (const GNUNET_PEER_Id peer);
358
359
360 /**
361  * Build a PeerPath from the paths returned from the DHT, reversing the paths
362  * to obtain a local peer -> destination path and interning the peer ids.
363  *
364  * @return Newly allocated and created path
365  */
366 static struct MeshPeerPath *
367 path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
368                      unsigned int get_path_length,
369                      const struct GNUNET_PeerIdentity *put_path,
370                      unsigned int put_path_length);
371
372
373 /**
374  * Adds a path to the data structs of all the peers in the path
375  *
376  * @param p Path to process.
377  * @param confirmed Whether we know if the path works or not.
378  */
379 static void
380 path_add_to_peers (struct MeshPeerPath *p, int confirmed);
381
382
383 /**
384  * Change the tunnel state.
385  *
386  * @param t Tunnel whose state to change.
387  * @param state New state.
388  */
389 static void
390 tunnel_change_state (struct MeshTunnel2 *t, enum MeshTunnelState state);
391
392
393 /**
394  * Notify a tunnel that a connection has broken that affects at least
395  * some of its peers.
396  *
397  * @param t Tunnel affected.
398  * @param p1 Peer that got disconnected from p2.
399  * @param p2 Peer that got disconnected from p1.
400  *
401  * @return Short ID of the peer disconnected (either p1 or p2).
402  *         0 if the tunnel remained unaffected.
403  */
404 static GNUNET_PEER_Id
405 tunnel_notify_connection_broken (struct MeshTunnel2 *t,
406                                  GNUNET_PEER_Id p1, GNUNET_PEER_Id p2);
407
408 /**
409  * @brief Use the given path for the tunnel.
410  * Update the next and prev hops (and RCs).
411  * (Re)start the path refresh in case the tunnel is locally owned.
412  *
413  * @param t Tunnel to update.
414  * @param p Path to use.
415  *
416  * @return Connection created.
417  */
418 static struct MeshConnection *
419 tunnel_use_path (struct MeshTunnel2 *t, struct MeshPeerPath *p);
420
421 /**
422  * Tunnel is empty: destroy it.
423  *
424  * Notifies all participants (peers, cleints) about the destruction.
425  *
426  * @param t Tunnel to destroy.
427  */
428 static void
429 tunnel_destroy_empty (struct MeshTunnel2 *t);
430
431 /**
432  * Destroy the tunnel.
433  *
434  * This function does not generate any warning traffic to clients or peers.
435  *
436  * Tasks:
437  * Cancel messages belonging to this tunnel queued to neighbors.
438  * Free any allocated resources linked to the tunnel.
439  *
440  * @param t The tunnel to destroy.
441  */
442 static void
443 tunnel_destroy (struct MeshTunnel2 *t);
444
445
446 /**
447  * Demultiplex by message type and call appropriate handler for a message
448  * towards a channel of a local tunnel.
449  *
450  * @param t Tunnel this message came on.
451  * @param msgh Message header.
452  * @param fwd Is this message fwd?
453  */
454 static void
455 handle_decrypted (struct MeshTunnel2 *t,
456                   const struct GNUNET_MessageHeader *msgh,
457                   int fwd);
458
459
460 /**
461  * Dummy function to separate declarations from definitions in function list.
462  */
463 void
464 __mesh_divider______________________________________________________________();
465
466
467 /**
468  * Get string description for tunnel state.
469  *
470  * @param s Tunnel state.
471  *
472  * @return String representation.
473  */
474 static const char *
475 GNUNET_MESH_DEBUG_TS2S (enum MeshTunnelState s)
476 {
477   static char buf[128];
478
479   switch (s)
480   {
481     case MESH_TUNNEL_NEW:
482       return "MESH_TUNNEL_NEW";
483     case MESH_TUNNEL_SEARCHING:
484       return "MESH_TUNNEL_SEARCHING";
485     case MESH_TUNNEL_WAITING:
486       return "MESH_TUNNEL_WAITING";
487     case MESH_TUNNEL_READY:
488       return "MESH_TUNNEL_READY";
489     case MESH_TUNNEL_RECONNECTING:
490       return "MESH_TUNNEL_RECONNECTING";
491
492     default:
493       sprintf (buf, "%u (UNKNOWN STATE)", s);
494       return buf;
495   }
496 }
497
498
499
500
501 /******************************************************************************/
502 /******************      GENERAL HELPER FUNCTIONS      ************************/
503 /******************************************************************************/
504
505
506 /**
507  * Get the static string for a peer ID.
508  *
509  * @param peer Peer.
510  *
511  * @return Static string for it's ID.
512  */
513 static const char *
514 peer2s (const struct MeshPeer *peer)
515 {
516   if (NULL == peer)
517     return "(NULL)";
518   return GNUNET_i2s (GNUNET_PEER_resolve2 (peer->id));
519 }
520
521
522
523 /**
524  * Count established (ready) connections of a tunnel.
525  *
526  * @param t Tunnel on which to send the message.
527  *
528  * @return Number of connections.
529  */
530 static unsigned int
531 tunnel_count_connections (struct MeshTunnel2 *t)
532 {
533   struct MeshConnection *c;
534   unsigned int i;
535
536   for (c = t->connection_head, i = 0; NULL != c; c = c->next, i++);
537
538   return i;
539 }
540
541
542 /**
543  * Pick a connection on which send the next data message.
544  *
545  * @param t Tunnel on which to send the message.
546  * @param fwd Is this a fwd message?
547  *
548  * @return The connection on which to send the next message.
549  */
550 static struct MeshConnection *
551 tunnel_get_connection (struct MeshTunnel2 *t, int fwd)
552 {
553   struct MeshConnection *c;
554   struct MeshConnection *best;
555   struct MeshFlowControl *fc;
556   unsigned int lowest_q;
557
558   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n",
559               peer2s (t->peer));
560   best = NULL;
561   lowest_q = UINT_MAX;
562   for (c = t->connection_head; NULL != c; c = c->next)
563   {
564     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  connection %s: %u\n",
565                 GNUNET_h2s (&c->id), c->state);
566     if (MESH_CONNECTION_READY == c->state)
567     {
568       fc = fwd ? &c->fwd_fc : &c->bck_fc;
569       if (NULL == fc)
570       {
571         GNUNET_break (0);
572         continue;
573       }
574       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    q_n %u, \n", fc->queue_n);
575       if (fc->queue_n < lowest_q)
576       {
577         best = c;
578         lowest_q = fc->queue_n;
579       }
580     }
581   }
582   return best;
583 }
584
585
586
587
588 /**
589  * Get the total buffer space for a tunnel.
590  *
591  * @param t Tunnel.
592  * @param fwd Is this for FWD traffic?
593  *
594  * @return Buffer space offered by all connections in the tunnel.
595  */
596 static unsigned int
597 tunnel_get_buffer (struct MeshTunnel2 *t, int fwd)
598 {
599   struct MeshConnection *c;
600   struct MeshFlowControl *fc;
601   unsigned int buffer;
602
603   c = t->connection_head;
604   buffer = 0;
605
606   /* If terminal, return biggest channel buffer */
607   if (NULL == c || GMC_is_terminal (c, fwd))
608   {
609     struct MeshChannel *ch;
610     unsigned int ch_buf;
611
612     if (NULL == t->channel_head)
613       return 64;
614
615     for (ch = t->channel_head; NULL != ch; ch = ch->next)
616     {
617       ch_buf = channel_get_buffer (ch, fwd);
618       if (ch_buf > buffer)
619         buffer = ch_buf;
620     }
621     return buffer;
622   }
623
624   /* If not terminal, return sum of connection buffers */
625   while (NULL != c)
626   {
627     if (c->state != MESH_CONNECTION_READY)
628     {
629       c = c->next;
630       continue;
631     }
632
633     fc = fwd ? &c->fwd_fc : &c->bck_fc;
634     buffer += fc->queue_max - fc->queue_n;
635     c = c->next;
636   }
637
638   return buffer;
639 }
640
641
642 /**
643  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
644  * Encrypt data with the tunnel key.
645  *
646  * @param t Tunnel whose key to use.
647  * @param dst Destination for the encrypted data.
648  * @param src Source of the plaintext.
649  * @param size Size of the plaintext.
650  * @param iv Initialization Vector to use.
651  * @param fwd Is this a fwd message?
652  */
653 static void
654 tunnel_encrypt (struct MeshTunnel2 *t,
655                 void *dst, const void *src,
656                 size_t size, uint64_t iv, int fwd)
657 {
658   memcpy (dst, src, size);
659 }
660
661
662 /**
663  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
664  * Decrypt data with the tunnel key.
665  *
666  * @param t Tunnel whose key to use.
667  * @param dst Destination for the plaintext.
668  * @param src Source of the encrypted data.
669  * @param size Size of the encrypted data.
670  * @param iv Initialization Vector to use.
671  * @param fwd Is this a fwd message?
672  */
673 static void
674 tunnel_decrypt (struct MeshTunnel2 *t,
675                 void *dst, const void *src,
676                 size_t size, uint64_t iv, int fwd)
677 {
678   memcpy (dst, src, size);
679 }
680
681
682 /**
683  * Sends an already built message on a tunnel, choosing the best connection.
684  *
685  * @param message Message to send. Function modifies it.
686  * @param t Tunnel on which this message is transmitted.
687  * @param ch Channel on which this message is transmitted.
688  * @param fwd Is this a fwd message?
689  */
690 static void
691 send_prebuilt_message_tunnel (struct GNUNET_MESH_Encrypted *msg,
692                               struct MeshTunnel2 *t,
693                               struct MeshChannel *ch,
694                               int fwd)
695 {
696   struct MeshConnection *c;
697   uint16_t type;
698
699   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n",
700               peer2s (t->peer));
701   c = tunnel_get_connection (t, fwd);
702   if (NULL == c)
703   {
704     GNUNET_break (GNUNET_YES == t->destroy);
705     return;
706   }
707   type = ntohs (msg->header.type);
708   switch (type)
709   {
710     case GNUNET_MESSAGE_TYPE_MESH_FWD:
711     case GNUNET_MESSAGE_TYPE_MESH_BCK:
712     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
713     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
714       msg->cid = c->id;
715       msg->ttl = htonl (default_ttl);
716       break;
717     default:
718       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "unkown type %s\n",
719                   GNUNET_MESH_DEBUG_M2S (type));
720       GNUNET_break (0);
721   }
722   msg->reserved = 0;
723
724   send_prebuilt_message_connection (&msg->header, c, ch, fwd);
725 }
726
727
728
729 /**
730  * Sends a CREATE CONNECTION message for a path to a peer.
731  * Changes the connection and tunnel states if necessary.
732  *
733  * @param connection Connection to create.
734  */
735 static void
736 send_connection_create (struct MeshConnection *connection)
737 {
738   struct MeshTunnel2 *t;
739
740   t = connection->t;
741   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send connection create\n");
742   queue_add (NULL,
743              GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE,
744              sizeof (struct GNUNET_MESH_ConnectionCreate) +
745                 (connection->path->length *
746                  sizeof (struct GNUNET_PeerIdentity)),
747              connection,
748              NULL,
749              GNUNET_YES);
750   if (NULL != t &&
751       (MESH_TUNNEL_SEARCHING == t->state || MESH_TUNNEL_NEW == t->state))
752     tunnel_change_state (t, MESH_TUNNEL_WAITING);
753   if (MESH_CONNECTION_NEW == connection->state)
754     connection_change_state (connection, MESH_CONNECTION_SENT);
755 }
756
757
758 /**
759  * Sends a CONNECTION ACK message in reponse to a received CONNECTION_CREATE
760  * directed to us.
761  *
762  * @param connection Connection to confirm.
763  * @param fwd Is this a fwd ACK? (First is bck (SYNACK), second is fwd (ACK))
764  */
765 static void
766 send_connection_ack (struct MeshConnection *connection, int fwd)
767 {
768   struct MeshTunnel2 *t;
769
770   t = connection->t;
771   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send connection ack\n");
772   queue_add (NULL,
773              GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK,
774              sizeof (struct GNUNET_MESH_ConnectionACK),
775              connection,
776              NULL,
777              fwd);
778   if (MESH_TUNNEL_NEW == t->state)
779     tunnel_change_state (t, MESH_TUNNEL_WAITING);
780   if (MESH_CONNECTION_READY != connection->state)
781     connection_change_state (connection, MESH_CONNECTION_SENT);
782 }
783
784
785 /**
786   * Core callback to write a pre-constructed data packet to core buffer
787   *
788   * @param cls Closure (MeshTransmissionDescriptor with data in "data" member).
789   * @param size Number of bytes available in buf.
790   * @param buf Where the to write the message.
791   *
792   * @return number of bytes written to buf
793   */
794 static size_t
795 send_core_data_raw (void *cls, size_t size, void *buf)
796 {
797   struct GNUNET_MessageHeader *msg = cls;
798   size_t total_size;
799
800   GNUNET_assert (NULL != msg);
801   total_size = ntohs (msg->size);
802
803   if (total_size > size)
804   {
805     GNUNET_break (0);
806     return 0;
807   }
808   memcpy (buf, msg, total_size);
809   GNUNET_free (cls);
810   return total_size;
811 }
812
813
814 /**
815  * Function to send a create connection message to a peer.
816  *
817  * @param c Connection to create.
818  * @param size number of bytes available in buf
819  * @param buf where the callee should write the message
820  * @return number of bytes written to buf
821  */
822 static size_t
823 send_core_connection_create (struct MeshConnection *c, size_t size, void *buf)
824 {
825   struct GNUNET_MESH_ConnectionCreate *msg;
826   struct GNUNET_PeerIdentity *peer_ptr;
827   struct MeshPeerPath *p = c->path;
828   size_t size_needed;
829   int i;
830
831   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending CONNECTION CREATE...\n");
832   size_needed =
833       sizeof (struct GNUNET_MESH_ConnectionCreate) +
834       p->length * sizeof (struct GNUNET_PeerIdentity);
835
836   if (size < size_needed || NULL == buf)
837   {
838     GNUNET_break (0);
839     return 0;
840   }
841   msg = (struct GNUNET_MESH_ConnectionCreate *) buf;
842   msg->header.size = htons (size_needed);
843   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE);
844   msg->cid = c->id;
845
846   peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1];
847   for (i = 0; i < p->length; i++)
848   {
849     GNUNET_PEER_resolve (p->peers[i], peer_ptr++);
850   }
851
852   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
853               "CONNECTION CREATE (%u bytes long) sent!\n", size_needed);
854   return size_needed;
855 }
856
857
858 /**
859  * Creates a path ack message in buf and frees all unused resources.
860  *
861  * @param c Connection to send an ACK on.
862  * @param size number of bytes available in buf
863  * @param buf where the callee should write the message
864  *
865  * @return number of bytes written to buf
866  */
867 static size_t
868 send_core_connection_ack (struct MeshConnection *c, size_t size, void *buf)
869 {
870   struct GNUNET_MESH_ConnectionACK *msg = buf;
871   struct MeshTunnel2 *t = c->t;
872
873   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending CONNECTION ACK...\n");
874   GNUNET_assert (NULL != t);
875   if (sizeof (struct GNUNET_MESH_ConnectionACK) > size)
876   {
877     GNUNET_break (0);
878     return 0;
879   }
880   msg->header.size = htons (sizeof (struct GNUNET_MESH_ConnectionACK));
881   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK);
882   msg->cid = c->id;
883   msg->reserved = 0;
884
885   /* TODO add signature */
886
887   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONNECTION ACK sent!\n");
888   return sizeof (struct GNUNET_MESH_ConnectionACK);
889 }
890
891
892
893 /**
894  * Adds a path to the peer_infos of all the peers in the path
895  *
896  * @param p Path to process.
897  * @param confirmed Whether we know if the path works or not.
898  */
899 static void
900 path_add_to_peers (struct MeshPeerPath *p, int confirmed)
901 {
902   unsigned int i;
903
904   /* TODO: invert and add */
905   for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ;
906   for (i++; i < p->length; i++)
907   {
908     struct MeshPeer *aux;
909     struct MeshPeerPath *copy;
910
911     aux = peer_get_short (p->peers[i]);
912     copy = path_duplicate (p);
913     copy->length = i + 1;
914     peer_add_path (aux, copy, p->length < 3 ? GNUNET_NO : confirmed);
915   }
916 }
917
918
919 #if 0
920 static void
921 fc_debug (struct MeshFlowControl *fc)
922 {
923   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    IN: %u/%u\n",
924               fc->last_pid_recv, fc->last_ack_sent);
925   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    OUT: %u/%u\n",
926               fc->last_pid_sent, fc->last_ack_recv);
927   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    QUEUE: %u/%u\n",
928               fc->queue_n, fc->queue_max);
929 }
930
931 static void
932 connection_debug (struct MeshConnection *c)
933 {
934   if (NULL == c)
935   {
936     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*** DEBUG NULL CONNECTION ***\n");
937     return;
938   }
939   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection %s:%X\n",
940               peer2s (c->t->peer), GNUNET_h2s (&c->id));
941   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  state: %u, pending msgs: %u\n",
942               c->state, c->pending_messages);
943   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  FWD FC\n");
944   fc_debug (&c->fwd_fc);
945   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  BCK FC\n");
946   fc_debug (&c->bck_fc);
947 }
948
949 #endif
950
951
952 /**
953  * Change the tunnel state.
954  *
955  * @param t Tunnel whose state to change.
956  * @param state New state.
957  */
958 static void
959 tunnel_change_state (struct MeshTunnel2* t, enum MeshTunnelState state)
960 {
961   if (NULL == t)
962     return;
963   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
964               "Tunnel %s state was %s\n",
965               peer2s (t->peer),
966               GNUNET_MESH_DEBUG_TS2S (t->state));
967   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
968               "Tunnel %s state is now %s\n",
969               peer2s (t->peer),
970               GNUNET_MESH_DEBUG_TS2S (state));
971   t->state = state;
972 }
973
974
975 /**
976  * Send all cached messages that we can, tunnel is online.
977  *
978  * @param t Tunnel that holds the messages.
979  * @param fwd Is this fwd?
980  */
981 static void
982 tunnel_send_queued_data (struct MeshTunnel2 *t, int fwd)
983 {
984   struct MeshTunnelQueue *tq;
985   struct MeshTunnelQueue *next;
986   unsigned int room;
987
988   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
989               "tunnel_send_queued_data on tunnel %s\n",
990               peer2s (t->peer));
991   room = tunnel_get_buffer (t, fwd);
992   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  buffer space: %u\n", room);
993   for (tq = t->tq_head; NULL != tq && room > 0; tq = next)
994   {
995     next = tq->next;
996     room--;
997     GNUNET_CONTAINER_DLL_remove (t->tq_head, t->tq_tail, tq);
998     send_prebuilt_message_channel ((struct GNUNET_MessageHeader *) &tq[1],
999                                    tq->ch, fwd);
1000
1001     GNUNET_free (tq);
1002   }
1003 }
1004
1005
1006 /**
1007  * Cache a message to be sent once tunnel is online.
1008  *
1009  * @param t Tunnel to hold the message.
1010  * @param ch Channel the message is about.
1011  * @param msg Message itself (copy will be made).
1012  * @param fwd Is this fwd?
1013  */
1014 static void
1015 tunnel_queue_data (struct MeshTunnel2 *t,
1016                    struct MeshChannel *ch,
1017                    struct GNUNET_MessageHeader *msg,
1018                    int fwd)
1019 {
1020   struct MeshTunnelQueue *tq;
1021   uint16_t size = ntohs (msg->size);
1022
1023   tq = GNUNET_malloc (sizeof (struct MeshTunnelQueue) + size);
1024
1025   tq->ch = ch;
1026   memcpy (&tq[1], msg, size);
1027   GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tq);
1028
1029   if (MESH_TUNNEL_READY == t->state)
1030     tunnel_send_queued_data (t, fwd);
1031 }
1032
1033
1034
1035
1036
1037 static struct MeshConnection *
1038 tunnel_use_path (struct MeshTunnel2 *t, struct MeshPeerPath *p)
1039 {
1040   struct MeshConnection *c;
1041   struct GNUNET_HashCode cid;
1042   struct MeshPeer *peer;
1043   unsigned int own_pos;
1044
1045   if (NULL == t || NULL == p)
1046   {
1047     GNUNET_break (0);
1048     return NULL;
1049   }
1050
1051   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, &cid);
1052
1053   c = connection_new (&cid);
1054   c->t = t;
1055   GNUNET_CONTAINER_DLL_insert (t->connection_head, t->connection_tail, c);
1056   for (own_pos = 0; own_pos < p->length; own_pos++)
1057   {
1058     if (p->peers[own_pos] == myid)
1059       break;
1060   }
1061   if (own_pos > p->length - 1)
1062   {
1063     GNUNET_break (0);
1064     connection_destroy (c);
1065     return NULL;
1066   }
1067   c->own_pos = own_pos;
1068   c->path = p;
1069
1070   if (0 == own_pos)
1071   {
1072     c->fwd_maintenance_task =
1073         GNUNET_SCHEDULER_add_delayed (refresh_connection_time,
1074                                       &connection_fwd_keepalive, c);
1075   }
1076
1077   peer = connection_get_next_hop (c);
1078   if (NULL == peer->connections)
1079   {
1080     connection_destroy (c);
1081     return NULL;
1082   }
1083   GNUNET_CONTAINER_multihashmap_put (peer->connections, &c->id, c,
1084                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1085   peer = connection_get_prev_hop (c);
1086   if (NULL == peer->connections)
1087   {
1088     connection_destroy (c);
1089     return NULL;
1090   }
1091   GNUNET_CONTAINER_multihashmap_put (peer->connections, &c->id, c,
1092                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1093   return c;
1094 }
1095
1096
1097 /**
1098  * Notifies a tunnel that a connection has broken that affects at least
1099  * some of its peers. Sends a notification towards the root of the tree.
1100  * In case the peer is the owner of the tree, notifies the client that owns
1101  * the tunnel and tries to reconnect.
1102  *
1103  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
1104  *
1105  * @param t Tunnel affected.
1106  * @param p1 Peer that got disconnected from p2.
1107  * @param p2 Peer that got disconnected from p1.
1108  *
1109  * @return Short ID of the peer disconnected (either p1 or p2).
1110  *         0 if the tunnel remained unaffected.
1111  */
1112 static GNUNET_PEER_Id
1113 tunnel_notify_connection_broken (struct MeshTunnel2* t,
1114                                  GNUNET_PEER_Id p1, GNUNET_PEER_Id p2)
1115 {
1116 //   if (myid != p1 && myid != p2) FIXME
1117 //   {
1118 //     return;
1119 //   }
1120 //
1121 //   if (tree_get_predecessor (t->tree) != 0)
1122 //   {
1123 //     /* We are the peer still connected, notify owner of the disconnection. */
1124 //     struct GNUNET_MESH_PathBroken msg;
1125 //     struct GNUNET_PeerIdentity neighbor;
1126 //
1127 //     msg.header.size = htons (sizeof (msg));
1128 //     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
1129 //     GNUNET_PEER_resolve (t->id.oid, &msg.oid);
1130 //     msg.tid = htonl (t->id.tid);
1131 //     msg.peer1 = my_full_id;
1132 //     GNUNET_PEER_resolve (pid, &msg.peer2);
1133 //     GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
1134 //     send_prebuilt_message (&msg.header, &neighbor, t);
1135 //   }
1136   return 0;
1137 }
1138
1139
1140
1141
1142 /**
1143  * Send an ACK on the appropriate connection/channel, depending on
1144  * the direction and the position of the peer.
1145  *
1146  * @param c Which connection to send the hop-by-hop ACK.
1147  * @param ch Channel, if any.
1148  * @param fwd Is this a fwd ACK? (will go dest->root)
1149  */
1150 static void
1151 send_ack (struct MeshConnection *c, struct MeshChannel *ch, int fwd)
1152 {
1153   unsigned int buffer;
1154
1155   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1156               "send ack %s on %p %p\n",
1157               fwd ? "FWD" : "BCK", c, ch);
1158   if (NULL == c || GMC_is_terminal (c, fwd))
1159   {
1160     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  getting from all connections\n");
1161     buffer = tunnel_get_buffer (NULL == c ? ch->t : c->t, fwd);
1162   }
1163   else
1164   {
1165     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  getting from one connection\n");
1166     buffer = connection_get_buffer (c, fwd);
1167   }
1168   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  buffer available: %u\n", buffer);
1169
1170   if ( (NULL != ch && channel_is_origin (ch, fwd)) ||
1171        (NULL != c && connection_is_origin (c, fwd)) )
1172   {
1173     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  sending on channel...\n");
1174     if (0 < buffer)
1175     {
1176       GNUNET_assert (NULL != ch);
1177       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  really sending!\n");
1178       send_local_ack (ch, fwd);
1179     }
1180   }
1181   else if (NULL == c)
1182   {
1183     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  sending on all connections\n");
1184     GNUNET_assert (NULL != ch);
1185     channel_send_connections_ack (ch, buffer, fwd);
1186   }
1187   else
1188   {
1189     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  sending on connection\n");
1190     connection_send_ack (c, buffer, fwd);
1191   }
1192 }
1193
1194
1195
1196
1197 /**
1198  * Confirm we got a channel create.
1199  *
1200  * @param ch The channel to confirm.
1201  * @param fwd Should we send the ACK fwd?
1202  */
1203 static void
1204 channel_send_ack (struct MeshChannel *ch, int fwd)
1205 {
1206   struct GNUNET_MESH_ChannelManage msg;
1207
1208   msg.header.size = htons (sizeof (msg));
1209   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK);
1210   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1211               "  sending channel %s ack for channel %s:%X\n",
1212               fwd ? "FWD" : "BCK", peer2s (ch->t->peer),
1213               ch->gid);
1214
1215   msg.chid = htonl (ch->gid);
1216   send_prebuilt_message_channel (&msg.header, ch, !fwd);
1217 }
1218
1219
1220 /**
1221  * Send a message to all clients (local and remote) of this channel
1222  * notifying that the channel is no longer valid.
1223  *
1224  * If some peer or client should not receive the message,
1225  * should be zero'ed out before calling this function.
1226  *
1227  * @param ch The channel whose clients to notify.
1228  */
1229 static void
1230 channel_send_destroy (struct MeshChannel *ch)
1231 {
1232   struct GNUNET_MESH_ChannelManage msg;
1233
1234   msg.header.size = htons (sizeof (msg));
1235   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY);
1236   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1237               "  sending channel destroy for channel %s:%X\n",
1238               peer2s (ch->t->peer),
1239               ch->gid);
1240
1241   if (channel_is_terminal (ch, GNUNET_NO))
1242   {
1243     if (NULL != ch->root && GNUNET_NO == ch->root->shutting_down)
1244     {
1245       msg.chid = htonl (ch->lid_root);
1246       send_local_channel_destroy (ch, GNUNET_NO);
1247     }
1248   }
1249   else
1250   {
1251     msg.chid = htonl (ch->gid);
1252     send_prebuilt_message_channel (&msg.header, ch, GNUNET_NO);
1253   }
1254
1255   if (channel_is_terminal (ch, GNUNET_YES))
1256   {
1257     if (NULL != ch->dest && GNUNET_NO == ch->dest->shutting_down)
1258     {
1259       msg.chid = htonl (ch->lid_dest);
1260       send_local_channel_destroy (ch, GNUNET_YES);
1261     }
1262   }
1263   else
1264   {
1265     msg.chid = htonl (ch->gid);
1266     send_prebuilt_message_channel (&msg.header, ch, GNUNET_YES);
1267   }
1268 }
1269
1270
1271 /**
1272  * Create a tunnel.
1273  */
1274 static struct MeshTunnel2 *
1275 tunnel_new (void)
1276 {
1277   struct MeshTunnel2 *t;
1278
1279   t = GNUNET_new (struct MeshTunnel2);
1280   t->next_chid = 0;
1281   t->next_local_chid = GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
1282 //   if (GNUNET_OK !=
1283 //       GNUNET_CONTAINER_multihashmap_put (tunnels, tid, t,
1284 //                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
1285 //   {
1286 //     GNUNET_break (0);
1287 //     tunnel_destroy (t);
1288 //     return NULL;
1289 //   }
1290
1291 //   char salt[] = "salt";
1292 //   GNUNET_CRYPTO_kdf (&t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1293 //                      salt, sizeof (salt),
1294 //                      &t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1295 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
1296 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
1297 //                      NULL);
1298 //   GNUNET_CRYPTO_kdf (&t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1299 //                      salt, sizeof (salt),
1300 //                      &t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1301 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
1302 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
1303 //                      NULL);
1304
1305   return t;
1306 }
1307
1308
1309 /**
1310  * Add a connection to a tunnel.
1311  *
1312  * @param t Tunnel.
1313  * @param c Connection.
1314  */
1315 static void
1316 tunnel_add_connection (struct MeshTunnel2 *t, struct MeshConnection *c)
1317 {
1318   struct MeshConnection *aux;
1319   c->t = t;
1320   for (aux = t->connection_head; aux != NULL; aux = aux->next)
1321     if (aux == c)
1322       return;
1323   GNUNET_CONTAINER_DLL_insert_tail (t->connection_head, t->connection_tail, c);
1324 }
1325
1326
1327
1328 static void
1329 tunnel_destroy (struct MeshTunnel2 *t)
1330 {
1331   struct MeshConnection *c;
1332   struct MeshConnection *next;
1333
1334   if (NULL == t)
1335     return;
1336
1337   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n",
1338               peer2s (t->peer));
1339
1340 //   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &t->id, t))
1341 //     GNUNET_break (0);
1342
1343   for (c = t->connection_head; NULL != c; c = next)
1344   {
1345     next = c->next;
1346     connection_destroy (c);
1347   }
1348
1349   GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
1350   t->peer->tunnel = NULL;
1351
1352   GNUNET_free (t);
1353 }
1354
1355
1356 /**
1357  * Tunnel is empty: destroy it.
1358  *
1359  * Notifies all connections about the destruction.
1360  *
1361  * @param t Tunnel to destroy.
1362  */
1363 static void
1364 tunnel_destroy_empty (struct MeshTunnel2 *t)
1365 {
1366   struct MeshConnection *c;
1367
1368   for (c = t->connection_head; NULL != c; c = c->next)
1369   {
1370     if (GNUNET_NO == c->destroy)
1371       connection_send_destroy (c);
1372   }
1373
1374   if (0 == t->pending_messages)
1375     tunnel_destroy (t);
1376   else
1377     t->destroy = GNUNET_YES;
1378 }
1379
1380
1381 /**
1382  * Destroy tunnel if empty (no more channels).
1383  *
1384  * @param t Tunnel to destroy if empty.
1385  */
1386 static void
1387 tunnel_destroy_if_empty (struct MeshTunnel2 *t)
1388 {
1389   if (NULL != t->channel_head)
1390     return;
1391
1392   tunnel_destroy_empty (t);
1393 }
1394
1395
1396 /******************************************************************************/
1397 /****************      MESH NETWORK HANDLER HELPERS     ***********************/
1398 /******************************************************************************/
1399
1400
1401
1402
1403
1404
1405 /******************************************************************************/
1406 /********************      MESH NETWORK HANDLERS     **************************/
1407 /******************************************************************************/
1408
1409
1410 /**
1411  * Generic handler for mesh network payload traffic.
1412  *
1413  * @param t Tunnel on which we got this message.
1414  * @param message Unencryted data message.
1415  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1416  */
1417 static void
1418 handle_data (struct MeshTunnel2 *t, const struct GNUNET_MESH_Data *msg, int fwd)
1419 {
1420   struct MeshChannelReliability *rel;
1421   struct MeshChannel *ch;
1422   struct MeshClient *c;
1423   uint32_t mid;
1424   uint16_t type;
1425   size_t size;
1426
1427   /* Check size */
1428   size = ntohs (msg->header.size);
1429   if (size <
1430       sizeof (struct GNUNET_MESH_Data) +
1431       sizeof (struct GNUNET_MessageHeader))
1432   {
1433     GNUNET_break (0);
1434     return;
1435   }
1436   type = ntohs (msg->header.type);
1437   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n",
1438               GNUNET_MESH_DEBUG_M2S (type));
1439   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n",
1440               GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
1441
1442   /* Check channel */
1443   ch = channel_get (t, ntohl (msg->chid));
1444   if (NULL == ch)
1445   {
1446     GNUNET_STATISTICS_update (stats, "# data on unknown channel", 1, GNUNET_NO);
1447     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
1448                 ntohl (msg->chid));
1449     return;
1450   }
1451
1452   /*  Initialize FWD/BCK data */
1453   c   = fwd ? ch->dest     : ch->root;
1454   rel = fwd ? ch->dest_rel : ch->root_rel;
1455
1456   if (NULL == c)
1457   {
1458     GNUNET_break (0);
1459     return;
1460   }
1461
1462   tunnel_change_state (t, MESH_TUNNEL_READY);
1463
1464   GNUNET_STATISTICS_update (stats, "# data received", 1, GNUNET_NO);
1465
1466   mid = ntohl (msg->mid);
1467   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " mid %u\n", mid);
1468
1469   if (GNUNET_NO == ch->reliable ||
1470       ( !GMC_is_pid_bigger (rel->mid_recv, mid) &&
1471         GMC_is_pid_bigger (rel->mid_recv + 64, mid) ) )
1472   {
1473     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! RECV %u\n", mid);
1474     if (GNUNET_YES == ch->reliable)
1475     {
1476       /* Is this the exact next expected messasge? */
1477       if (mid == rel->mid_recv)
1478       {
1479         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "as expected\n");
1480         rel->mid_recv++;
1481         channel_send_client_data (ch, msg, fwd);
1482       }
1483       else
1484       {
1485         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "save for later\n");
1486         channel_rel_add_buffered_data (msg, rel);
1487       }
1488     }
1489     else
1490     {
1491       /* Tunnel is unreliable: send to clients directly */
1492       /* FIXME: accept Out Of Order traffic */
1493       rel->mid_recv = mid + 1;
1494       channel_send_client_data (ch, msg, fwd);
1495     }
1496   }
1497   else
1498   {
1499     GNUNET_break_op (0);
1500     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1501                 " MID %u not expected (%u - %u), dropping!\n",
1502                 mid, rel->mid_recv, rel->mid_recv + 64);
1503   }
1504
1505   channel_send_data_ack (ch, fwd);
1506 }
1507
1508 /**
1509  * Handler for mesh network traffic end-to-end ACKs.
1510  *
1511  * @param t Tunnel on which we got this message.
1512  * @param message Data message.
1513  * @param fwd Is this a fwd ACK? (dest->orig)
1514  */
1515 static void
1516 handle_data_ack (struct MeshTunnel2 *t,
1517                  const struct GNUNET_MESH_DataACK *msg, int fwd)
1518 {
1519   struct MeshChannelReliability *rel;
1520   struct MeshReliableMessage *copy;
1521   struct MeshReliableMessage *next;
1522   struct MeshChannel *ch;
1523   uint32_t ack;
1524   uint16_t type;
1525   int work;
1526
1527   type = ntohs (msg->header.type);
1528   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a %s message!\n",
1529               GNUNET_MESH_DEBUG_M2S (type));
1530   ch = channel_get (t, ntohl (msg->chid));
1531   if (NULL == ch)
1532   {
1533     GNUNET_STATISTICS_update (stats, "# ack on unknown channel", 1, GNUNET_NO);
1534     return;
1535   }
1536   ack = ntohl (msg->mid);
1537   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! %s ACK %u\n",
1538               (GNUNET_YES == fwd) ? "FWD" : "BCK", ack);
1539
1540   if (GNUNET_YES == fwd)
1541   {
1542     rel = ch->root_rel;
1543   }
1544   else
1545   {
1546     rel = ch->dest_rel;
1547   }
1548   if (NULL == rel)
1549   {
1550     GNUNET_break (0);
1551     return;
1552   }
1553
1554   for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next)
1555   {
1556     if (GMC_is_pid_bigger (copy->mid, ack))
1557     {
1558       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!!  head %u, out!\n", copy->mid);
1559       channel_rel_free_sent (rel, msg);
1560       break;
1561     }
1562     work = GNUNET_YES;
1563     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!!  id %u\n", copy->mid);
1564     next = copy->next;
1565     rel_message_free (copy);
1566   }
1567   /* ACK client if needed */
1568 //   channel_send_ack (t, type, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK == type);
1569
1570   /* If some message was free'd, update the retransmission delay*/
1571   if (GNUNET_YES == work)
1572   {
1573     if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
1574     {
1575       GNUNET_SCHEDULER_cancel (rel->retry_task);
1576       if (NULL == rel->head_sent)
1577       {
1578         rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
1579       }
1580       else
1581       {
1582         struct GNUNET_TIME_Absolute new_target;
1583         struct GNUNET_TIME_Relative delay;
1584
1585         delay = GNUNET_TIME_relative_multiply (rel->retry_timer,
1586                                                MESH_RETRANSMIT_MARGIN);
1587         new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp,
1588                                                delay);
1589         delay = GNUNET_TIME_absolute_get_remaining (new_target);
1590         rel->retry_task =
1591             GNUNET_SCHEDULER_add_delayed (delay,
1592                                           &channel_retransmit_message,
1593                                           rel);
1594       }
1595     }
1596     else
1597       GNUNET_break (0);
1598   }
1599 }
1600
1601
1602
1603
1604 /**
1605  * Handler for channel create messages.
1606  *
1607  * @param t Tunnel this channel is to be created in.
1608  * @param msg Message.
1609  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1610  */
1611 static void
1612 handle_channel_create (struct MeshTunnel2 *t,
1613                        struct GNUNET_MESH_ChannelCreate *msg,
1614                        int fwd)
1615 {
1616   MESH_ChannelNumber chid;
1617   struct MeshChannel *ch;
1618   struct MeshClient *c;
1619   uint32_t port;
1620
1621   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Channel Create\n");
1622   /* Check message size */
1623   if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelCreate))
1624   {
1625     GNUNET_break_op (0);
1626     return;
1627   }
1628
1629   /* Check if channel exists */
1630   chid = ntohl (msg->chid);
1631   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   chid %u\n", chid);
1632   ch = channel_get (t, chid);
1633   if (NULL != ch)
1634   {
1635     /* Probably a retransmission, safe to ignore */
1636     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   already exists...\n");
1637     if (NULL != ch->dest)
1638     {
1639       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   duplicate CC!!\n");
1640       channel_send_ack (ch, !fwd);
1641       return;
1642     }
1643   }
1644   else
1645   {
1646     /* Create channel */
1647     ch = channel_new (t, NULL, 0);
1648     ch->gid = chid;
1649     channel_set_options (ch, ntohl (msg->opt));
1650   }
1651
1652   /* Find a destination client */
1653   port = ntohl (msg->port);
1654   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   port %u\n", port);
1655   c = GNUNET_CONTAINER_multihashmap32_get (ports, port);
1656   if (NULL == c)
1657   {
1658     /* TODO send reject */
1659     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  no client has port registered\n");
1660     /* TODO free ch */
1661     return;
1662   }
1663
1664   channel_add_client (ch, c);
1665   if (GNUNET_YES == ch->reliable)
1666     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! Reliable\n");
1667
1668   send_local_channel_create (ch);
1669   channel_send_ack (ch, fwd);
1670   send_local_ack (ch, !fwd);
1671 }
1672
1673
1674 /**
1675  * Handler for channel ack messages.
1676  *
1677  * @param t Tunnel this channel is to be created in.
1678  * @param msg Message.
1679  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1680  */
1681 static void
1682 handle_channel_ack (struct MeshTunnel2 *t,
1683                     struct GNUNET_MESH_ChannelManage *msg,
1684                     int fwd)
1685 {
1686   MESH_ChannelNumber chid;
1687   struct MeshChannel *ch;
1688
1689   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Channel ACK\n");
1690   /* Check message size */
1691   if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage))
1692   {
1693     GNUNET_break_op (0);
1694     return;
1695   }
1696
1697   /* Check if channel exists */
1698   chid = ntohl (msg->chid);
1699   ch = channel_get (t, chid);
1700   if (NULL == ch)
1701   {
1702     GNUNET_break_op (0);
1703     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   channel %u unknown!!\n", chid);
1704     return;
1705   }
1706
1707   channel_confirm (ch, !fwd);
1708 }
1709
1710
1711 /**
1712  * Handler for channel destroy messages.
1713  *
1714  * @param t Tunnel this channel is to be destroyed of.
1715  * @param msg Message.
1716  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1717  */
1718 static void
1719 handle_channel_destroy (struct MeshTunnel2 *t,
1720                         struct GNUNET_MESH_ChannelManage *msg,
1721                         int fwd)
1722 {
1723   MESH_ChannelNumber chid;
1724   struct MeshChannel *ch;
1725
1726   /* Check message size */
1727   if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage))
1728   {
1729     GNUNET_break_op (0);
1730     return;
1731   }
1732
1733   /* Check if channel exists */
1734   chid = ntohl (msg->chid);
1735   ch = channel_get (t, chid);
1736   if (NULL == ch)
1737   {
1738     /* Probably a retransmission, safe to ignore */
1739     return;
1740   }
1741   if ( (fwd && NULL == ch->dest) || (!fwd && NULL == ch->root) )
1742   {
1743     /* Not for us (don't destroy twice a half-open loopback channel) */
1744     return;
1745   }
1746
1747   send_local_channel_destroy (ch, fwd);
1748   channel_destroy (ch);
1749 }
1750
1751
1752 static void
1753 handle_decrypted (struct MeshTunnel2 *t,
1754                   const struct GNUNET_MessageHeader *msgh,
1755                   int fwd)
1756 {
1757   switch (ntohs (msgh->type))
1758   {
1759     case GNUNET_MESSAGE_TYPE_MESH_DATA:
1760       /* Don't send hop ACK, wait for client to ACK */
1761       handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd);
1762       break;
1763
1764     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
1765       handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd);
1766       break;
1767
1768     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
1769       handle_channel_create (t,
1770                              (struct GNUNET_MESH_ChannelCreate *) msgh,
1771                              fwd);
1772       break;
1773
1774     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
1775       handle_channel_ack (t,
1776                           (struct GNUNET_MESH_ChannelManage *) msgh,
1777                           fwd);
1778       break;
1779
1780     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
1781       handle_channel_destroy (t,
1782                               (struct GNUNET_MESH_ChannelManage *) msgh,
1783                               fwd);
1784       break;
1785
1786     default:
1787       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1788                   "end-to-end message not known (%u)\n",
1789                   ntohs (msgh->type));
1790   }
1791 }
1792
1793
1794 /**
1795  * Function to process paths received for a new peer addition. The recorded
1796  * paths form the initial tunnel, which can be optimized later.
1797  * Called on each result obtained for the DHT search.
1798  *
1799  * @param cls closure
1800  * @param path
1801  */
1802 static void
1803 search_handler (void *cls, struct MeshPeerPath *path)
1804 {
1805   struct MeshConnection *c;
1806   unsigned int connection_count;
1807
1808   path_add_to_peers (path, GNUNET_NO);
1809
1810   /* Count connections */
1811   connection_count = GMC_count (peer->tunnel->connection_head);
1812
1813   /* If we already have 3 (or more (?!)) connections, it's enough */
1814   if (3 <= connection_count)
1815     return;
1816
1817   if (peer->tunnel->state == MESH_TUNNEL_SEARCHING)
1818   {
1819     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... connect!\n");
1820     peer_connect (peer);
1821   }
1822   return;
1823 }
1824
1825
1826 /******************************************************************************/
1827 /************************      MAIN FUNCTIONS      ****************************/
1828 /******************************************************************************/
1829
1830
1831
1832
1833 /**
1834  * Task run during shutdown.
1835  *
1836  * @param cls unused
1837  * @param tc unused
1838  */
1839 static void
1840 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1841 {
1842   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutting down\n");
1843
1844   GML_shutdown ();
1845   GMD_shutdown ();
1846   GMP_shutdown ();
1847   GMC_shutdown ();
1848
1849   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n");
1850 }
1851
1852
1853 /**
1854  * Process mesh requests.
1855  *
1856  * @param cls closure
1857  * @param server the initialized server
1858  * @param c configuration to use
1859  */
1860 static void
1861 run (void *cls, struct GNUNET_SERVER_Handle *server,
1862      const struct GNUNET_CONFIGURATION_Handle *c)
1863 {
1864   struct GNUNET_CRYPTO_EccPrivateKey *pk;
1865
1866   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n");
1867
1868   if (GNUNET_OK !=
1869       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "CONNECT_TIMEOUT",
1870                                            &connect_timeout))
1871   {
1872     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
1873                                "MESH", "CONNECT_TIMEOUT", "MISSING");
1874     GNUNET_SCHEDULER_shutdown ();
1875     return;
1876   }
1877
1878   if (GNUNET_OK !=
1879       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL",
1880                                              &default_ttl))
1881   {
1882     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1883                                "MESH", "DEFAULT_TTL", "USING DEFAULT");
1884     default_ttl = 64;
1885   }
1886
1887   if (GNUNET_OK !=
1888       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DROP_PERCENT",
1889                                              &drop_percent))
1890   {
1891     drop_percent = 0;
1892   }
1893   else
1894   {
1895     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1896                 "\n***************************************\n"
1897                 "Mesh is running with drop mode enabled.\n"
1898                 "This is NOT a good idea!\n"
1899                 "Remove the DROP_PERCENT option from your configuration.\n"
1900                 "***************************************\n");
1901   }
1902
1903
1904   stats = GNUNET_STATISTICS_create ("mesh", c);
1905
1906   /* Scheduled the task to clean up when shutdown is called */
1907   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
1908                                 NULL);
1909   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "reading key\n");
1910   pk = GNUNET_CRYPTO_ecc_key_create_from_configuration (c);
1911   GNUNET_assert (NULL != pk);
1912   my_private_key = pk;
1913   GNUNET_CRYPTO_ecc_key_get_public_for_signature (my_private_key,
1914                                                   &my_full_id.public_key);
1915   myid = GNUNET_PEER_intern (&my_full_id);
1916   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1917               "Mesh for peer [%s] starting\n",
1918               GNUNET_i2s(&my_full_id));
1919
1920   GML_init (server);    /* Local clients */
1921   GMC_init (c);         /* Connections */
1922   GMP_init (c);         /* Peers */
1923   GMD_init (c, &my_full_id);         /* DHT */
1924
1925   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh service running\n");
1926 }
1927
1928
1929 /**
1930  * The main function for the mesh service.
1931  *
1932  * @param argc number of arguments from the command line
1933  * @param argv command line arguments
1934  * @return 0 ok, 1 on error
1935  */
1936 int
1937 main (int argc, char *const *argv)
1938 {
1939   int ret;
1940   int r;
1941
1942   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main()\n");
1943   r = GNUNET_SERVICE_run (argc, argv, "mesh", GNUNET_SERVICE_OPTION_NONE, &run,
1944                           NULL);
1945   ret = (GNUNET_OK == r) ? 0 : 1;
1946   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main() END\n");
1947
1948   INTERVAL_SHOW;
1949
1950   return ret;
1951 }