-remove generated binary
[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  * Get string description for tunnel state.
501  *
502  * @param s Tunnel state.
503  *
504  * @return String representation. 
505  */
506 static const char *
507 GNUNET_MESH_DEBUG_CS2S (enum MeshTunnelState s)
508 {
509   switch (s) 
510   {
511     case MESH_CONNECTION_NEW:
512       return "MESH_CONNECTION_NEW";
513     case MESH_CONNECTION_SENT:
514       return "MESH_CONNECTION_SENT";
515     case MESH_CONNECTION_ACK:
516       return "MESH_CONNECTION_ACK";
517     case MESH_CONNECTION_READY:
518       return "MESH_CONNECTION_READY";
519     default:
520       return "MESH_CONNECTION_STATE_ERROR";
521   }
522 }
523
524
525
526 /******************************************************************************/
527 /******************      GENERAL HELPER FUNCTIONS      ************************/
528 /******************************************************************************/
529
530
531 /**
532  * Get the static string for a peer ID.
533  *
534  * @param peer Peer.
535  *
536  * @return Static string for it's ID.
537  */
538 static const char *
539 peer2s (const struct MeshPeer *peer)
540 {
541   if (NULL == peer)
542     return "(NULL)";
543   return GNUNET_i2s (GNUNET_PEER_resolve2 (peer->id));
544 }
545
546
547
548 /**
549  * Count established (ready) connections of a tunnel.
550  *
551  * @param t Tunnel on which to send the message.
552  *
553  * @return Number of connections.
554  */
555 static unsigned int
556 tunnel_count_connections (struct MeshTunnel2 *t)
557 {
558   struct MeshConnection *c;
559   unsigned int i;
560
561   for (c = t->connection_head, i = 0; NULL != c; c = c->next, i++);
562
563   return i;
564 }
565
566
567 /**
568  * Pick a connection on which send the next data message.
569  *
570  * @param t Tunnel on which to send the message.
571  * @param fwd Is this a fwd message?
572  *
573  * @return The connection on which to send the next message.
574  */
575 static struct MeshConnection *
576 tunnel_get_connection (struct MeshTunnel2 *t, int fwd)
577 {
578   struct MeshConnection *c;
579   struct MeshConnection *best;
580   struct MeshFlowControl *fc;
581   unsigned int lowest_q;
582
583   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n",
584               peer2s (t->peer));
585   best = NULL;
586   lowest_q = UINT_MAX;
587   for (c = t->connection_head; NULL != c; c = c->next)
588   {
589     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  connection %s: %u\n",
590                 GNUNET_h2s (&c->id), c->state);
591     if (MESH_CONNECTION_READY == c->state)
592     {
593       fc = fwd ? &c->fwd_fc : &c->bck_fc;
594       if (NULL == fc)
595       {
596         GNUNET_break (0);
597         continue;
598       }
599       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    q_n %u, \n", fc->queue_n);
600       if (fc->queue_n < lowest_q)
601       {
602         best = c;
603         lowest_q = fc->queue_n;
604       }
605     }
606   }
607   return best;
608 }
609
610
611
612
613 /**
614  * Get the total buffer space for a tunnel.
615  *
616  * @param t Tunnel.
617  * @param fwd Is this for FWD traffic?
618  *
619  * @return Buffer space offered by all connections in the tunnel.
620  */
621 static unsigned int
622 tunnel_get_buffer (struct MeshTunnel2 *t, int fwd)
623 {
624   struct MeshConnection *c;
625   struct MeshFlowControl *fc;
626   unsigned int buffer;
627
628   c = t->connection_head;
629   buffer = 0;
630
631   /* If terminal, return biggest channel buffer */
632   if (NULL == c || GMC_is_terminal (c, fwd))
633   {
634     struct MeshChannel *ch;
635     unsigned int ch_buf;
636
637     if (NULL == t->channel_head)
638       return 64;
639
640     for (ch = t->channel_head; NULL != ch; ch = ch->next)
641     {
642       ch_buf = channel_get_buffer (ch, fwd);
643       if (ch_buf > buffer)
644         buffer = ch_buf;
645     }
646     return buffer;
647   }
648
649   /* If not terminal, return sum of connection buffers */
650   while (NULL != c)
651   {
652     if (c->state != MESH_CONNECTION_READY)
653     {
654       c = c->next;
655       continue;
656     }
657
658     fc = fwd ? &c->fwd_fc : &c->bck_fc;
659     buffer += fc->queue_max - fc->queue_n;
660     c = c->next;
661   }
662
663   return buffer;
664 }
665
666
667 /**
668  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME 
669  * Encrypt data with the tunnel key.
670  *
671  * @param t Tunnel whose key to use.
672  * @param dst Destination for the encrypted data.
673  * @param src Source of the plaintext.
674  * @param size Size of the plaintext.
675  * @param iv Initialization Vector to use.
676  * @param fwd Is this a fwd message?
677  */
678 static void
679 tunnel_encrypt (struct MeshTunnel2 *t,
680                 void *dst, const void *src,
681                 size_t size, uint64_t iv, int fwd)
682 {
683   memcpy (dst, src, size);
684 }
685
686
687 /**
688  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME 
689  * Decrypt data with the tunnel key.
690  *
691  * @param t Tunnel whose key to use.
692  * @param dst Destination for the plaintext.
693  * @param src Source of the encrypted data.
694  * @param size Size of the encrypted data.
695  * @param iv Initialization Vector to use.
696  * @param fwd Is this a fwd message?
697  */
698 static void
699 tunnel_decrypt (struct MeshTunnel2 *t,
700                 void *dst, const void *src,
701                 size_t size, uint64_t iv, int fwd)
702 {
703   memcpy (dst, src, size);
704 }
705
706
707 /**
708  * Sends an already built message on a tunnel, choosing the best connection.
709  *
710  * @param message Message to send. Function modifies it.
711  * @param t Tunnel on which this message is transmitted.
712  * @param ch Channel on which this message is transmitted.
713  * @param fwd Is this a fwd message?
714  */
715 static void
716 send_prebuilt_message_tunnel (struct GNUNET_MESH_Encrypted *msg,
717                               struct MeshTunnel2 *t,
718                               struct MeshChannel *ch,
719                               int fwd)
720 {
721   struct MeshConnection *c;
722   uint16_t type;
723
724   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n",
725               peer2s (t->peer));
726   c = tunnel_get_connection (t, fwd);
727   if (NULL == c)
728   {
729     GNUNET_break (GNUNET_YES == t->destroy);
730     return;
731   }
732   type = ntohs (msg->header.type);
733   switch (type)
734   {
735     case GNUNET_MESSAGE_TYPE_MESH_FWD:
736     case GNUNET_MESSAGE_TYPE_MESH_BCK:
737     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
738     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
739       msg->cid = c->id;
740       msg->ttl = htonl (default_ttl);
741       break;
742     default:
743       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "unkown type %s\n",
744                   GNUNET_MESH_DEBUG_M2S (type));
745       GNUNET_break (0);
746   }
747   msg->reserved = 0;
748
749   send_prebuilt_message_connection (&msg->header, c, ch, fwd);
750 }
751
752
753
754 /**
755  * Sends a CREATE CONNECTION message for a path to a peer.
756  * Changes the connection and tunnel states if necessary.
757  *
758  * @param connection Connection to create.
759  */
760 static void
761 send_connection_create (struct MeshConnection *connection)
762 {
763   struct MeshTunnel2 *t;
764
765   t = connection->t;
766   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send connection create\n");
767   queue_add (NULL,
768              GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE,
769              sizeof (struct GNUNET_MESH_ConnectionCreate) +
770                 (connection->path->length *
771                  sizeof (struct GNUNET_PeerIdentity)),
772              connection,
773              NULL,
774              GNUNET_YES);
775   if (NULL != t &&
776       (MESH_TUNNEL_SEARCHING == t->state || MESH_TUNNEL_NEW == t->state))
777     tunnel_change_state (t, MESH_TUNNEL_WAITING);
778   if (MESH_CONNECTION_NEW == connection->state)
779     connection_change_state (connection, MESH_CONNECTION_SENT);
780 }
781
782
783 /**
784  * Sends a CONNECTION ACK message in reponse to a received CONNECTION_CREATE
785  * directed to us.
786  *
787  * @param connection Connection to confirm.
788  * @param fwd Is this a fwd ACK? (First is bck (SYNACK), second is fwd (ACK))
789  */
790 static void
791 send_connection_ack (struct MeshConnection *connection, int fwd) 
792 {
793   struct MeshTunnel2 *t;
794
795   t = connection->t;
796   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send connection ack\n");
797   queue_add (NULL,
798              GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK,
799              sizeof (struct GNUNET_MESH_ConnectionACK),
800              connection,
801              NULL,
802              fwd);
803   if (MESH_TUNNEL_NEW == t->state)
804     tunnel_change_state (t, MESH_TUNNEL_WAITING);
805   if (MESH_CONNECTION_READY != connection->state)
806     connection_change_state (connection, MESH_CONNECTION_SENT);
807 }
808
809
810 /**
811   * Core callback to write a pre-constructed data packet to core buffer
812   *
813   * @param cls Closure (MeshTransmissionDescriptor with data in "data" member).
814   * @param size Number of bytes available in buf.
815   * @param buf Where the to write the message.
816   *
817   * @return number of bytes written to buf
818   */
819 static size_t
820 send_core_data_raw (void *cls, size_t size, void *buf)
821 {
822   struct GNUNET_MessageHeader *msg = cls;
823   size_t total_size;
824
825   GNUNET_assert (NULL != msg);
826   total_size = ntohs (msg->size);
827
828   if (total_size > size)
829   {
830     GNUNET_break (0);
831     return 0;
832   }
833   memcpy (buf, msg, total_size);
834   GNUNET_free (cls);
835   return total_size;
836 }
837
838
839 /**
840  * Function to send a create connection message to a peer.
841  *
842  * @param c Connection to create.
843  * @param size number of bytes available in buf
844  * @param buf where the callee should write the message
845  * @return number of bytes written to buf
846  */
847 static size_t
848 send_core_connection_create (struct MeshConnection *c, size_t size, void *buf)
849 {
850   struct GNUNET_MESH_ConnectionCreate *msg;
851   struct GNUNET_PeerIdentity *peer_ptr;
852   struct MeshPeerPath *p = c->path;
853   size_t size_needed;
854   int i;
855
856   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending CONNECTION CREATE...\n");
857   size_needed =
858       sizeof (struct GNUNET_MESH_ConnectionCreate) +
859       p->length * sizeof (struct GNUNET_PeerIdentity);
860
861   if (size < size_needed || NULL == buf)
862   {
863     GNUNET_break (0);
864     return 0;
865   }
866   msg = (struct GNUNET_MESH_ConnectionCreate *) buf;
867   msg->header.size = htons (size_needed);
868   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE);
869   msg->cid = c->id;
870
871   peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1];
872   for (i = 0; i < p->length; i++)
873   {
874     GNUNET_PEER_resolve (p->peers[i], peer_ptr++);
875   }
876
877   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
878               "CONNECTION CREATE (%u bytes long) sent!\n", size_needed);
879   return size_needed;
880 }
881
882
883 /**
884  * Creates a path ack message in buf and frees all unused resources.
885  *
886  * @param c Connection to send an ACK on.
887  * @param size number of bytes available in buf
888  * @param buf where the callee should write the message
889  *
890  * @return number of bytes written to buf
891  */
892 static size_t
893 send_core_connection_ack (struct MeshConnection *c, size_t size, void *buf)
894 {
895   struct GNUNET_MESH_ConnectionACK *msg = buf;
896   struct MeshTunnel2 *t = c->t;
897
898   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending CONNECTION ACK...\n");
899   GNUNET_assert (NULL != t);
900   if (sizeof (struct GNUNET_MESH_ConnectionACK) > size)
901   {
902     GNUNET_break (0);
903     return 0;
904   }
905   msg->header.size = htons (sizeof (struct GNUNET_MESH_ConnectionACK));
906   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK);
907   msg->cid = c->id;
908   msg->reserved = 0;
909
910   /* TODO add signature */
911
912   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONNECTION ACK sent!\n");
913   return sizeof (struct GNUNET_MESH_ConnectionACK);
914 }
915
916
917 /**
918  * Destroy the peer_info and free any allocated resources linked to it
919  *
920  * @param peer The peer_info to destroy.
921  *
922  * @return GNUNET_OK on success
923  */
924 static int
925 peer_destroy (struct MeshPeer *peer)
926 {
927   struct GNUNET_PeerIdentity id;
928   struct MeshPeerPath *p;
929   struct MeshPeerPath *nextp;
930
931   GNUNET_PEER_resolve (peer->id, &id);
932   GNUNET_PEER_change_rc (peer->id, -1);
933
934   if (GNUNET_YES !=
935       GNUNET_CONTAINER_multipeermap_remove (peers, &id, peer))
936   {
937     GNUNET_break (0);
938     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
939                 "removing peer %s, not in peermap\n", GNUNET_i2s (&id));
940   }
941   if (NULL != peer->dhtget)
942   {
943     GNUNET_DHT_get_stop (peer->dhtget);
944   }
945   p = peer->path_head;
946   while (NULL != p)
947   {
948     nextp = p->next;
949     GNUNET_CONTAINER_DLL_remove (peer->path_head, peer->path_tail, p);
950     path_destroy (p);
951     p = nextp;
952   }
953   tunnel_destroy_empty (peer->tunnel);
954   GNUNET_free (peer);
955   return GNUNET_OK;
956 }
957
958
959 /**
960  * Returns if peer is used (has a tunnel, is neighbor).
961  *
962  * @peer Peer to check.
963  *
964  * @return GNUNET_YES if peer is in use.
965  */
966 static int
967 peer_is_used (struct MeshPeer *peer)
968 {
969   struct MeshPeerPath *p;
970
971   if (NULL != peer->tunnel)
972     return GNUNET_YES;
973
974   for (p = peer->path_head; NULL != p; p = p->next)
975   {
976     if (p->length < 3)
977       return GNUNET_YES;
978   }
979   return GNUNET_NO;
980 }
981
982
983 /**
984  * Iterator over all the peers to get the oldest timestamp.
985  *
986  * @param cls Closure (unsued).
987  * @param key ID of the peer.
988  * @param value Peer_Info of the peer.
989  */
990 static int
991 peer_get_oldest (void *cls,
992                  const struct GNUNET_PeerIdentity *key,
993                  void *value)
994 {
995   struct MeshPeer *p = value;
996   struct GNUNET_TIME_Absolute *abs = cls;
997
998   /* Don't count active peers */
999   if (GNUNET_YES == peer_is_used (p))
1000     return GNUNET_YES;
1001
1002   if (abs->abs_value_us < p->last_contact.abs_value_us)
1003     abs->abs_value_us = p->last_contact.abs_value_us;
1004
1005   return GNUNET_YES;
1006 }
1007
1008
1009 /**
1010  * Iterator over all the peers to remove the oldest entry.
1011  *
1012  * @param cls Closure (unsued).
1013  * @param key ID of the peer.
1014  * @param value Peer_Info of the peer.
1015  */
1016 static int
1017 peer_timeout (void *cls,
1018               const struct GNUNET_PeerIdentity *key,
1019               void *value)
1020 {
1021   struct MeshPeer *p = value;
1022   struct GNUNET_TIME_Absolute *abs = cls;
1023
1024   if (p->last_contact.abs_value_us == abs->abs_value_us &&
1025       GNUNET_NO == peer_is_used (p))
1026   {
1027     peer_destroy (p);
1028     return GNUNET_NO;
1029   }
1030   return GNUNET_YES;
1031 }
1032
1033
1034 /**
1035  * Delete oldest unused peer.
1036  */
1037 static void
1038 peer_delete_oldest (void)
1039 {
1040   struct GNUNET_TIME_Absolute abs;
1041
1042   abs = GNUNET_TIME_UNIT_FOREVER_ABS;
1043
1044   GNUNET_CONTAINER_multipeermap_iterate (peers,
1045                                          &peer_get_oldest,
1046                                          &abs);
1047   GNUNET_CONTAINER_multipeermap_iterate (peers,
1048                                          &peer_timeout,
1049                                          &abs);
1050 }
1051
1052
1053 /**
1054  * Retrieve the MeshPeer stucture associated with the peer, create one
1055  * and insert it in the appropriate structures if the peer is not known yet.
1056  *
1057  * @param peer Full identity of the peer.
1058  *
1059  * @return Existing or newly created peer info.
1060  */
1061 static struct MeshPeer *
1062 peer_get (const struct GNUNET_PeerIdentity *peer_id)
1063 {
1064   struct MeshPeer *peer;
1065
1066   peer = GNUNET_CONTAINER_multipeermap_get (peers, peer_id);
1067   if (NULL == peer)
1068   {
1069     peer = GNUNET_new (struct MeshPeer);
1070     if (GNUNET_CONTAINER_multipeermap_size (peers) > max_peers)
1071     {
1072       peer_delete_oldest ();
1073     }
1074     GNUNET_CONTAINER_multipeermap_put (peers, peer_id, peer,
1075                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1076     peer->id = GNUNET_PEER_intern (peer_id);
1077   }
1078   peer->last_contact = GNUNET_TIME_absolute_get();
1079
1080   return peer;
1081 }
1082
1083
1084 /**
1085  * Retrieve the MeshPeer stucture associated with the peer, create one
1086  * and insert it in the appropriate structures if the peer is not known yet.
1087  *
1088  * @param peer Short identity of the peer.
1089  *
1090  * @return Existing or newly created peer info.
1091  */
1092 static struct MeshPeer *
1093 peer_get_short (const GNUNET_PEER_Id peer)
1094 {
1095   return peer_get (GNUNET_PEER_resolve2 (peer));
1096 }
1097
1098
1099 /**
1100  * Get a cost of a path for a peer considering existing tunnel connections.
1101  *
1102  * @param peer Peer towards which the path is considered.
1103  * @param path Candidate path.
1104  *
1105  * @return Cost of the path (path length + number of overlapping nodes)
1106  */
1107 static unsigned int
1108 peer_get_path_cost (const struct MeshPeer *peer,
1109                     const struct MeshPeerPath *path)
1110 {
1111   struct MeshConnection *c;
1112   unsigned int overlap;
1113   unsigned int i;
1114   unsigned int j;
1115
1116   if (NULL == path)
1117     return 0;
1118
1119   overlap = 0;
1120   GNUNET_assert (NULL != peer->tunnel);
1121
1122   for (i = 0; i < path->length; i++)
1123   {
1124     for (c = peer->tunnel->connection_head; NULL != c; c = c->next)
1125     {
1126       for (j = 0; j < c->path->length; j++)
1127       {
1128         if (path->peers[i] == c->path->peers[j])
1129         {
1130           overlap++;
1131           break;
1132         }
1133       }
1134     }
1135   }
1136   return (path->length + overlap) * (path->score * -1);
1137 }
1138
1139
1140 /**
1141  * Choose the best path towards a peer considering the tunnel properties.
1142  *
1143  * @param peer The destination peer.
1144  *
1145  * @return Best current known path towards the peer, if any.
1146  */
1147 static struct MeshPeerPath *
1148 peer_get_best_path (const struct MeshPeer *peer)
1149 {
1150   struct MeshPeerPath *best_p;
1151   struct MeshPeerPath *p;
1152   struct MeshConnection *c;
1153   unsigned int best_cost;
1154   unsigned int cost;
1155
1156   best_cost = UINT_MAX;
1157   best_p = NULL;
1158   for (p = peer->path_head; NULL != p; p = p->next)
1159   {
1160     for (c = peer->tunnel->connection_head; NULL != c; c = c->next)
1161       if (c->path == p)
1162         break;
1163     if (NULL != c)
1164       continue; /* If path is in use in a connection, skip it. */
1165
1166     if ((cost = peer_get_path_cost (peer, p)) < best_cost)
1167     {
1168       best_cost = cost;
1169       best_p = p;
1170     }
1171   }
1172   return best_p;
1173 }
1174
1175
1176
1177 /**
1178  * Try to establish a new connection to this peer in the given tunnel.
1179  * If the peer doesn't have any path to it yet, try to get one.
1180  * If the peer already has some path, send a CREATE CONNECTION towards it.
1181  *
1182  * @param peer PeerInfo of the peer.
1183  */
1184 static void
1185 peer_connect (struct MeshPeer *peer)
1186 {
1187   struct MeshTunnel2 *t;
1188   struct MeshPeerPath *p;
1189   struct MeshConnection *c;
1190   int rerun_dhtget;
1191
1192   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1193               "peer_connect towards %s\n",
1194               peer2s (peer));
1195   t = peer->tunnel;
1196   c = NULL;
1197   rerun_dhtget = GNUNET_NO;
1198
1199   if (NULL != peer->path_head)
1200   {
1201     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "path exists\n");
1202     p = peer_get_best_path (peer);
1203     if (NULL != p)
1204     {
1205       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  %u hops\n", p->length);
1206       c = tunnel_use_path (t, p);
1207       if (NULL == c)
1208       {
1209         /* This case can happen when the path includes a first hop that is
1210          * not yet known to be connected.
1211          * 
1212          * This happens quite often during testing when running mesh
1213          * under valgrind: core connect notifications come very late and the
1214          * DHT result has already come and created a valid path.
1215          * In this case, the peer->connections hashmap will be NULL and
1216          * tunnel_use_path will not be able to create a connection from that
1217          * path.
1218          *
1219          * Re-running the DHT GET should give core time to callback.
1220          */
1221         GNUNET_break(0);
1222         rerun_dhtget = GNUNET_YES;
1223       }
1224       else
1225       {
1226         send_connection_create (c);
1227         return;
1228       }
1229     }
1230   }
1231
1232   if (NULL != peer->dhtget && GNUNET_YES == rerun_dhtget)
1233   {
1234     GNUNET_DHT_get_stop (peer->dhtget);
1235     peer->dhtget = NULL;
1236     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1237                 "  Stopping DHT GET for peer %s\n", peer2s (peer));
1238   }
1239
1240   if (NULL == peer->dhtget)
1241   {
1242     const struct GNUNET_PeerIdentity *id;
1243     struct GNUNET_HashCode phash;
1244
1245     id = GNUNET_PEER_resolve2 (peer->id);
1246     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1247                 "  Starting DHT GET for peer %s\n", peer2s (peer));
1248     GNUNET_CRYPTO_hash (&id, sizeof (struct GNUNET_PeerIdentity), &phash);
1249     peer->dhtget = GNUNET_DHT_get_start (dht_handle,    /* handle */
1250                                          GNUNET_BLOCK_TYPE_MESH_PEER, /* type */
1251                                          &phash,     /* key to search */
1252                                          dht_replication_level, /* replication level */
1253                                          GNUNET_DHT_RO_RECORD_ROUTE |
1254                                          GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
1255                                          NULL,       /* xquery */
1256                                          0,     /* xquery bits */
1257                                          &dht_get_id_handler, peer);
1258     if (MESH_TUNNEL_NEW == t->state)
1259       tunnel_change_state (t, MESH_TUNNEL_SEARCHING);
1260   }
1261 }
1262
1263
1264
1265 /**
1266  * Add the path to the peer and update the path used to reach it in case this
1267  * is the shortest.
1268  *
1269  * @param peer_info Destination peer to add the path to.
1270  * @param path New path to add. Last peer must be the peer in arg 1.
1271  *             Path will be either used of freed if already known.
1272  * @param trusted Do we trust that this path is real?
1273  */
1274 void
1275 peer_add_path (struct MeshPeer *peer_info, struct MeshPeerPath *path,
1276                     int trusted)
1277 {
1278   struct MeshPeerPath *aux;
1279   unsigned int l;
1280   unsigned int l2;
1281
1282   if ((NULL == peer_info) || (NULL == path))
1283   {
1284     GNUNET_break (0);
1285     path_destroy (path);
1286     return;
1287   }
1288   if (path->peers[path->length - 1] != peer_info->id)
1289   {
1290     GNUNET_break (0);
1291     path_destroy (path);
1292     return;
1293   }
1294   if (2 >= path->length && GNUNET_NO == trusted)
1295   {
1296     /* Only allow CORE to tell us about direct paths */
1297     path_destroy (path);
1298     return;
1299   }
1300   for (l = 1; l < path->length; l++)
1301   {
1302     if (path->peers[l] == myid)
1303     {
1304       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shortening path by %u\n", l);
1305       for (l2 = 0; l2 < path->length - l; l2++)
1306       {
1307         path->peers[l2] = path->peers[l + l2];
1308       }
1309       path->length -= l;
1310       l = 1;
1311       path->peers =
1312           GNUNET_realloc (path->peers, path->length * sizeof (GNUNET_PEER_Id));
1313     }
1314   }
1315
1316   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "adding path [%u] to peer %s\n",
1317               path->length, peer2s (peer_info));
1318
1319   l = path_get_length (path);
1320   if (0 == l)
1321   {
1322     path_destroy (path);
1323     return;
1324   }
1325
1326   GNUNET_assert (peer_info->id == path->peers[path->length - 1]);
1327   for (aux = peer_info->path_head; aux != NULL; aux = aux->next)
1328   {
1329     l2 = path_get_length (aux);
1330     if (l2 > l)
1331     {
1332       GNUNET_CONTAINER_DLL_insert_before (peer_info->path_head,
1333                                           peer_info->path_tail, aux, path);
1334       return;
1335     }
1336     else
1337     {
1338       if (l2 == l && memcmp (path->peers, aux->peers, l) == 0)
1339       {
1340         path_destroy (path);
1341         return;
1342       }
1343     }
1344   }
1345   GNUNET_CONTAINER_DLL_insert_tail (peer_info->path_head, peer_info->path_tail,
1346                                     path);
1347   return;
1348 }
1349
1350
1351 /**
1352  * Add the path to the origin peer and update the path used to reach it in case
1353  * this is the shortest.
1354  * The path is given in peer_info -> destination, therefore we turn the path
1355  * upside down first.
1356  *
1357  * @param peer_info Peer to add the path to, being the origin of the path.
1358  * @param path New path to add after being inversed.
1359  *             Path will be either used or freed.
1360  * @param trusted Do we trust that this path is real?
1361  */
1362 static void
1363 peer_add_path_to_origin (struct MeshPeer *peer_info,
1364                          struct MeshPeerPath *path, int trusted)
1365 {
1366   if (NULL == path)
1367     return;
1368   path_invert (path);
1369   peer_add_path (peer_info, path, trusted);
1370 }
1371
1372 /**
1373  * Build a PeerPath from the paths returned from the DHT, reversing the paths
1374  * to obtain a local peer -> destination path and interning the peer ids.
1375  *
1376  * @return Newly allocated and created path
1377  */
1378 static struct MeshPeerPath *
1379 path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
1380                      unsigned int get_path_length,
1381                      const struct GNUNET_PeerIdentity *put_path,
1382                      unsigned int put_path_length)
1383 {
1384   struct MeshPeerPath *p;
1385   GNUNET_PEER_Id id;
1386   int i;
1387
1388   p = path_new (1);
1389   p->peers[0] = myid;
1390   GNUNET_PEER_change_rc (myid, 1);
1391   i = get_path_length;
1392   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   GET has %d hops.\n", i);
1393   for (i--; i >= 0; i--)
1394   {
1395     id = GNUNET_PEER_intern (&get_path[i]);
1396     if (p->length > 0 && id == p->peers[p->length - 1])
1397     {
1398       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   Optimizing 1 hop out.\n");
1399       GNUNET_PEER_change_rc (id, -1);
1400     }
1401     else
1402     {
1403       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   Adding from GET: %s.\n",
1404                   GNUNET_i2s (&get_path[i]));
1405       p->length++;
1406       p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
1407       p->peers[p->length - 1] = id;
1408     }
1409   }
1410   i = put_path_length;
1411   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   PUT has %d hops.\n", i);
1412   for (i--; i >= 0; i--)
1413   {
1414     id = GNUNET_PEER_intern (&put_path[i]);
1415     if (id == myid)
1416     {
1417       /* PUT path went through us, so discard the path up until now and start
1418        * from here to get a much shorter (and loop-free) path.
1419        */
1420       path_destroy (p);
1421       p = path_new (0);
1422     }
1423     if (p->length > 0 && id == p->peers[p->length - 1])
1424     {
1425       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   Optimizing 1 hop out.\n");
1426       GNUNET_PEER_change_rc (id, -1);
1427     }
1428     else
1429     {
1430       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   Adding from PUT: %s.\n",
1431                   GNUNET_i2s (&put_path[i]));
1432       p->length++;
1433       p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
1434       p->peers[p->length - 1] = id;
1435     }
1436   }
1437 #if MESH_DEBUG
1438   if (get_path_length > 0)
1439     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   (first of GET: %s)\n",
1440                 GNUNET_i2s (&get_path[0]));
1441   if (put_path_length > 0)
1442     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   (first of PUT: %s)\n",
1443                 GNUNET_i2s (&put_path[0]));
1444   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   In total: %d hops\n",
1445               p->length);
1446   for (i = 0; i < p->length; i++)
1447   {
1448     struct GNUNET_PeerIdentity peer_id;
1449
1450     GNUNET_PEER_resolve (p->peers[i], &peer_id);
1451     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "       %u: %s\n", p->peers[i],
1452                 GNUNET_i2s (&peer_id));
1453   }
1454 #endif
1455   return p;
1456 }
1457
1458
1459 /**
1460  * Adds a path to the peer_infos of all the peers in the path
1461  *
1462  * @param p Path to process.
1463  * @param confirmed Whether we know if the path works or not.
1464  */
1465 static void
1466 path_add_to_peers (struct MeshPeerPath *p, int confirmed)
1467 {
1468   unsigned int i;
1469
1470   /* TODO: invert and add */
1471   for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ;
1472   for (i++; i < p->length; i++)
1473   {
1474     struct MeshPeer *aux;
1475     struct MeshPeerPath *copy;
1476
1477     aux = peer_get_short (p->peers[i]);
1478     copy = path_duplicate (p);
1479     copy->length = i + 1;
1480     peer_add_path (aux, copy, p->length < 3 ? GNUNET_NO : confirmed);
1481   }
1482 }
1483
1484
1485 #if 0
1486 static void
1487 fc_debug (struct MeshFlowControl *fc)
1488 {
1489   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    IN: %u/%u\n",
1490               fc->last_pid_recv, fc->last_ack_sent);
1491   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    OUT: %u/%u\n",
1492               fc->last_pid_sent, fc->last_ack_recv);
1493   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    QUEUE: %u/%u\n",
1494               fc->queue_n, fc->queue_max);
1495 }
1496
1497 static void
1498 connection_debug (struct MeshConnection *c)
1499 {
1500   if (NULL == c)
1501   {
1502     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*** DEBUG NULL CONNECTION ***\n");
1503     return;
1504   }
1505   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection %s:%X\n",
1506               peer2s (c->t->peer), GNUNET_h2s (&c->id));
1507   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  state: %u, pending msgs: %u\n", 
1508               c->state, c->pending_messages);
1509   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  FWD FC\n");
1510   fc_debug (&c->fwd_fc);
1511   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  BCK FC\n");
1512   fc_debug (&c->bck_fc);
1513 }
1514
1515 #endif
1516
1517
1518 /**
1519  * Change the tunnel state.
1520  *
1521  * @param t Tunnel whose state to change.
1522  * @param state New state.
1523  */
1524 static void
1525 tunnel_change_state (struct MeshTunnel2* t, enum MeshTunnelState state)
1526 {
1527   if (NULL == t)
1528     return;
1529   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1530               "Tunnel %s state was %s\n",
1531               peer2s (t->peer),
1532               GNUNET_MESH_DEBUG_TS2S (t->state));
1533   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1534               "Tunnel %s state is now %s\n",
1535               peer2s (t->peer),
1536               GNUNET_MESH_DEBUG_TS2S (state));
1537   t->state = state;
1538 }
1539
1540
1541 /**
1542  * Send all cached messages that we can, tunnel is online.
1543  *
1544  * @param t Tunnel that holds the messages.
1545  * @param fwd Is this fwd?
1546  */
1547 static void
1548 tunnel_send_queued_data (struct MeshTunnel2 *t, int fwd)
1549 {
1550   struct MeshTunnelQueue *tq;
1551   struct MeshTunnelQueue *next;
1552   unsigned int room;
1553
1554   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1555               "tunnel_send_queued_data on tunnel %s\n",
1556               peer2s (t->peer));
1557   room = tunnel_get_buffer (t, fwd);
1558   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  buffer space: %u\n", room);
1559   for (tq = t->tq_head; NULL != tq && room > 0; tq = next)
1560   {
1561     next = tq->next;
1562     room--;
1563     GNUNET_CONTAINER_DLL_remove (t->tq_head, t->tq_tail, tq);
1564     send_prebuilt_message_channel ((struct GNUNET_MessageHeader *) &tq[1],
1565                                    tq->ch, fwd);
1566
1567     GNUNET_free (tq);
1568   }
1569 }
1570
1571
1572 /**
1573  * Cache a message to be sent once tunnel is online.
1574  *
1575  * @param t Tunnel to hold the message.
1576  * @param ch Channel the message is about.
1577  * @param msg Message itself (copy will be made).
1578  * @param fwd Is this fwd?
1579  */
1580 static void
1581 tunnel_queue_data (struct MeshTunnel2 *t,
1582                    struct MeshChannel *ch,
1583                    struct GNUNET_MessageHeader *msg,
1584                    int fwd)
1585 {
1586   struct MeshTunnelQueue *tq;
1587   uint16_t size = ntohs (msg->size);
1588
1589   tq = GNUNET_malloc (sizeof (struct MeshTunnelQueue) + size);
1590
1591   tq->ch = ch;
1592   memcpy (&tq[1], msg, size);
1593   GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tq);
1594
1595   if (MESH_TUNNEL_READY == t->state)
1596     tunnel_send_queued_data (t, fwd);
1597 }
1598
1599
1600
1601
1602
1603 static struct MeshConnection *
1604 tunnel_use_path (struct MeshTunnel2 *t, struct MeshPeerPath *p)
1605 {
1606   struct MeshConnection *c;
1607   struct GNUNET_HashCode cid;
1608   struct MeshPeer *peer;
1609   unsigned int own_pos;
1610
1611   if (NULL == t || NULL == p)
1612   {
1613     GNUNET_break (0);
1614     return NULL;
1615   }
1616
1617   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, &cid);
1618
1619   c = connection_new (&cid);
1620   c->t = t;
1621   GNUNET_CONTAINER_DLL_insert (t->connection_head, t->connection_tail, c);
1622   for (own_pos = 0; own_pos < p->length; own_pos++)
1623   {
1624     if (p->peers[own_pos] == myid)
1625       break;
1626   }
1627   if (own_pos > p->length - 1)
1628   {
1629     GNUNET_break (0);
1630     connection_destroy (c);
1631     return NULL;
1632   }
1633   c->own_pos = own_pos;
1634   c->path = p;
1635
1636   if (0 == own_pos)
1637   {
1638     c->fwd_maintenance_task =
1639         GNUNET_SCHEDULER_add_delayed (refresh_connection_time,
1640                                       &connection_fwd_keepalive, c);
1641   }
1642
1643   peer = connection_get_next_hop (c);
1644   if (NULL == peer->connections)
1645   {
1646     connection_destroy (c);
1647     return NULL;
1648   }
1649   GNUNET_CONTAINER_multihashmap_put (peer->connections, &c->id, c,
1650                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1651   peer = connection_get_prev_hop (c);
1652   if (NULL == peer->connections)
1653   {
1654     connection_destroy (c);
1655     return NULL;
1656   }
1657   GNUNET_CONTAINER_multihashmap_put (peer->connections, &c->id, c,
1658                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1659   return c;
1660 }
1661
1662
1663 /**
1664  * Notifies a tunnel that a connection has broken that affects at least
1665  * some of its peers. Sends a notification towards the root of the tree.
1666  * In case the peer is the owner of the tree, notifies the client that owns
1667  * the tunnel and tries to reconnect.
1668  * 
1669  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME 
1670  *
1671  * @param t Tunnel affected.
1672  * @param p1 Peer that got disconnected from p2.
1673  * @param p2 Peer that got disconnected from p1.
1674  *
1675  * @return Short ID of the peer disconnected (either p1 or p2).
1676  *         0 if the tunnel remained unaffected.
1677  */
1678 static GNUNET_PEER_Id
1679 tunnel_notify_connection_broken (struct MeshTunnel2* t,
1680                                  GNUNET_PEER_Id p1, GNUNET_PEER_Id p2)
1681 {
1682 //   if (myid != p1 && myid != p2) FIXME
1683 //   {
1684 //     return;
1685 //   }
1686 // 
1687 //   if (tree_get_predecessor (t->tree) != 0)
1688 //   {
1689 //     /* We are the peer still connected, notify owner of the disconnection. */
1690 //     struct GNUNET_MESH_PathBroken msg;
1691 //     struct GNUNET_PeerIdentity neighbor;
1692 // 
1693 //     msg.header.size = htons (sizeof (msg));
1694 //     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
1695 //     GNUNET_PEER_resolve (t->id.oid, &msg.oid);
1696 //     msg.tid = htonl (t->id.tid);
1697 //     msg.peer1 = my_full_id;
1698 //     GNUNET_PEER_resolve (pid, &msg.peer2);
1699 //     GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
1700 //     send_prebuilt_message (&msg.header, &neighbor, t);
1701 //   }
1702   return 0;
1703 }
1704
1705
1706
1707
1708 /**
1709  * Send an ACK on the appropriate connection/channel, depending on
1710  * the direction and the position of the peer.
1711  *
1712  * @param c Which connection to send the hop-by-hop ACK.
1713  * @param ch Channel, if any.
1714  * @param fwd Is this a fwd ACK? (will go dest->root)
1715  */
1716 static void
1717 send_ack (struct MeshConnection *c, struct MeshChannel *ch, int fwd)
1718 {
1719   unsigned int buffer;
1720
1721   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1722               "send ack %s on %p %p\n",
1723               fwd ? "FWD" : "BCK", c, ch);
1724   if (NULL == c || GMC_is_terminal (c, fwd))
1725   {
1726     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  getting from all connections\n");
1727     buffer = tunnel_get_buffer (NULL == c ? ch->t : c->t, fwd);
1728   }
1729   else
1730   {
1731     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  getting from one connection\n");
1732     buffer = connection_get_buffer (c, fwd);
1733   }
1734   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  buffer available: %u\n", buffer);
1735
1736   if ( (NULL != ch && channel_is_origin (ch, fwd)) ||
1737        (NULL != c && connection_is_origin (c, fwd)) )
1738   {
1739     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  sending on channel...\n");
1740     if (0 < buffer)
1741     {
1742       GNUNET_assert (NULL != ch);
1743       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  really sending!\n");
1744       send_local_ack (ch, fwd);
1745     }
1746   }
1747   else if (NULL == c)
1748   {
1749     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  sending on all connections\n");
1750     GNUNET_assert (NULL != ch);
1751     channel_send_connections_ack (ch, buffer, fwd);
1752   }
1753   else 
1754   {
1755     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  sending on connection\n");
1756     connection_send_ack (c, buffer, fwd);
1757   }
1758 }
1759
1760
1761
1762
1763 /**
1764  * Confirm we got a channel create.
1765  *
1766  * @param ch The channel to confirm.
1767  * @param fwd Should we send the ACK fwd?
1768  */
1769 static void
1770 channel_send_ack (struct MeshChannel *ch, int fwd)
1771 {
1772   struct GNUNET_MESH_ChannelManage msg;
1773
1774   msg.header.size = htons (sizeof (msg));
1775   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK);
1776   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1777               "  sending channel %s ack for channel %s:%X\n",
1778               fwd ? "FWD" : "BCK", peer2s (ch->t->peer),
1779               ch->gid);
1780
1781   msg.chid = htonl (ch->gid);
1782   send_prebuilt_message_channel (&msg.header, ch, !fwd);
1783 }
1784
1785
1786 /**
1787  * Send a message to all clients (local and remote) of this channel
1788  * notifying that the channel is no longer valid.
1789  *
1790  * If some peer or client should not receive the message,
1791  * should be zero'ed out before calling this function.
1792  *
1793  * @param ch The channel whose clients to notify.
1794  */
1795 static void
1796 channel_send_destroy (struct MeshChannel *ch)
1797 {
1798   struct GNUNET_MESH_ChannelManage msg;
1799
1800   msg.header.size = htons (sizeof (msg));
1801   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY);
1802   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1803               "  sending channel destroy for channel %s:%X\n",
1804               peer2s (ch->t->peer),
1805               ch->gid);
1806
1807   if (channel_is_terminal (ch, GNUNET_NO))
1808   {
1809     if (NULL != ch->root && GNUNET_NO == ch->root->shutting_down)
1810     {
1811       msg.chid = htonl (ch->lid_root);
1812       send_local_channel_destroy (ch, GNUNET_NO);
1813     }
1814   }
1815   else
1816   {
1817     msg.chid = htonl (ch->gid);
1818     send_prebuilt_message_channel (&msg.header, ch, GNUNET_NO);
1819   }
1820
1821   if (channel_is_terminal (ch, GNUNET_YES))
1822   {
1823     if (NULL != ch->dest && GNUNET_NO == ch->dest->shutting_down)
1824     {
1825       msg.chid = htonl (ch->lid_dest);
1826       send_local_channel_destroy (ch, GNUNET_YES);
1827     }
1828   }
1829   else
1830   {
1831     msg.chid = htonl (ch->gid);
1832     send_prebuilt_message_channel (&msg.header, ch, GNUNET_YES);
1833   }
1834 }
1835
1836
1837 /**
1838  * Create a tunnel.
1839  */
1840 static struct MeshTunnel2 *
1841 tunnel_new (void)
1842 {
1843   struct MeshTunnel2 *t;
1844
1845   t = GNUNET_new (struct MeshTunnel2);
1846   t->next_chid = 0;
1847   t->next_local_chid = GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
1848 //   if (GNUNET_OK !=
1849 //       GNUNET_CONTAINER_multihashmap_put (tunnels, tid, t,
1850 //                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
1851 //   {
1852 //     GNUNET_break (0);
1853 //     tunnel_destroy (t);
1854 //     return NULL;
1855 //   }
1856
1857 //   char salt[] = "salt";
1858 //   GNUNET_CRYPTO_kdf (&t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1859 //                      salt, sizeof (salt),
1860 //                      &t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1861 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
1862 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
1863 //                      NULL);
1864 //   GNUNET_CRYPTO_kdf (&t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1865 //                      salt, sizeof (salt),
1866 //                      &t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1867 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
1868 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
1869 //                      NULL);
1870
1871   return t;
1872 }
1873
1874
1875 /**
1876  * Add a connection to a tunnel.
1877  *
1878  * @param t Tunnel.
1879  * @param c Connection.
1880  */
1881 static void
1882 tunnel_add_connection (struct MeshTunnel2 *t, struct MeshConnection *c)
1883 {
1884   struct MeshConnection *aux;
1885   c->t = t;
1886   for (aux = t->connection_head; aux != NULL; aux = aux->next)
1887     if (aux == c)
1888       return;
1889   GNUNET_CONTAINER_DLL_insert_tail (t->connection_head, t->connection_tail, c);
1890 }
1891
1892
1893
1894 static void
1895 tunnel_destroy (struct MeshTunnel2 *t)
1896 {
1897   struct MeshConnection *c;
1898   struct MeshConnection *next;
1899
1900   if (NULL == t)
1901     return;
1902
1903   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n",
1904               peer2s (t->peer));
1905
1906 //   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &t->id, t))
1907 //     GNUNET_break (0);
1908
1909   for (c = t->connection_head; NULL != c; c = next)
1910   {
1911     next = c->next;
1912     connection_destroy (c);
1913   }
1914
1915   GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
1916   t->peer->tunnel = NULL;
1917
1918   GNUNET_free (t);
1919 }
1920
1921
1922 /**
1923  * Tunnel is empty: destroy it.
1924  *
1925  * Notifies all connections about the destruction.
1926  *
1927  * @param t Tunnel to destroy. 
1928  */
1929 static void
1930 tunnel_destroy_empty (struct MeshTunnel2 *t)
1931 {
1932   struct MeshConnection *c;
1933
1934   for (c = t->connection_head; NULL != c; c = c->next)
1935   {
1936     if (GNUNET_NO == c->destroy)
1937       connection_send_destroy (c);
1938   }
1939
1940   if (0 == t->pending_messages)
1941     tunnel_destroy (t);
1942   else
1943     t->destroy = GNUNET_YES;
1944 }
1945
1946
1947 /**
1948  * Destroy tunnel if empty (no more channels).
1949  *
1950  * @param t Tunnel to destroy if empty.
1951  */
1952 static void
1953 tunnel_destroy_if_empty (struct MeshTunnel2 *t)
1954 {
1955   if (NULL != t->channel_head)
1956     return;
1957
1958   tunnel_destroy_empty (t);
1959 }
1960
1961
1962 /******************************************************************************/
1963 /****************      MESH NETWORK HANDLER HELPERS     ***********************/
1964 /******************************************************************************/
1965
1966
1967
1968
1969
1970
1971 /******************************************************************************/
1972 /********************      MESH NETWORK HANDLERS     **************************/
1973 /******************************************************************************/
1974
1975
1976 /**
1977  * Generic handler for mesh network payload traffic.
1978  *
1979  * @param t Tunnel on which we got this message.
1980  * @param message Unencryted data message.
1981  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1982  */
1983 static void
1984 handle_data (struct MeshTunnel2 *t, const struct GNUNET_MESH_Data *msg, int fwd)
1985 {
1986   struct MeshChannelReliability *rel;
1987   struct MeshChannel *ch;
1988   struct MeshClient *c;
1989   uint32_t mid;
1990   uint16_t type;
1991   size_t size;
1992
1993   /* Check size */
1994   size = ntohs (msg->header.size);
1995   if (size <
1996       sizeof (struct GNUNET_MESH_Data) +
1997       sizeof (struct GNUNET_MessageHeader))
1998   {
1999     GNUNET_break (0);
2000     return;
2001   }
2002   type = ntohs (msg->header.type);
2003   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n",
2004               GNUNET_MESH_DEBUG_M2S (type));
2005   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n",
2006               GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
2007
2008   /* Check channel */
2009   ch = channel_get (t, ntohl (msg->chid));
2010   if (NULL == ch)
2011   {
2012     GNUNET_STATISTICS_update (stats, "# data on unknown channel", 1, GNUNET_NO);
2013     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
2014                 ntohl (msg->chid));
2015     return;
2016   }
2017
2018   /*  Initialize FWD/BCK data */
2019   c   = fwd ? ch->dest     : ch->root;
2020   rel = fwd ? ch->dest_rel : ch->root_rel;
2021
2022   if (NULL == c)
2023   {
2024     GNUNET_break (0);
2025     return;
2026   }
2027
2028   tunnel_change_state (t, MESH_TUNNEL_READY);
2029
2030   GNUNET_STATISTICS_update (stats, "# data received", 1, GNUNET_NO);
2031
2032   mid = ntohl (msg->mid);
2033   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " mid %u\n", mid);
2034
2035   if (GNUNET_NO == ch->reliable ||
2036       ( !GMC_is_pid_bigger (rel->mid_recv, mid) &&
2037         GMC_is_pid_bigger (rel->mid_recv + 64, mid) ) )
2038   {
2039     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! RECV %u\n", mid);
2040     if (GNUNET_YES == ch->reliable)
2041     {
2042       /* Is this the exact next expected messasge? */
2043       if (mid == rel->mid_recv)
2044       {
2045         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "as expected\n");
2046         rel->mid_recv++;
2047         channel_send_client_data (ch, msg, fwd);
2048       }
2049       else
2050       {
2051         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "save for later\n");
2052         channel_rel_add_buffered_data (msg, rel);
2053       }
2054     }
2055     else
2056     {
2057       /* Tunnel is unreliable: send to clients directly */
2058       /* FIXME: accept Out Of Order traffic */
2059       rel->mid_recv = mid + 1;
2060       channel_send_client_data (ch, msg, fwd);
2061     }
2062   }
2063   else
2064   {
2065     GNUNET_break_op (0);
2066     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2067                 " MID %u not expected (%u - %u), dropping!\n",
2068                 mid, rel->mid_recv, rel->mid_recv + 64);
2069   }
2070
2071   channel_send_data_ack (ch, fwd);
2072 }
2073
2074 /**
2075  * Handler for mesh network traffic end-to-end ACKs.
2076  *
2077  * @param t Tunnel on which we got this message.
2078  * @param message Data message.
2079  * @param fwd Is this a fwd ACK? (dest->orig)
2080  */
2081 static void
2082 handle_data_ack (struct MeshTunnel2 *t,
2083                  const struct GNUNET_MESH_DataACK *msg, int fwd)
2084 {
2085   struct MeshChannelReliability *rel;
2086   struct MeshReliableMessage *copy;
2087   struct MeshReliableMessage *next;
2088   struct MeshChannel *ch;
2089   uint32_t ack;
2090   uint16_t type;
2091   int work;
2092
2093   type = ntohs (msg->header.type);
2094   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a %s message!\n",
2095               GNUNET_MESH_DEBUG_M2S (type));
2096   ch = channel_get (t, ntohl (msg->chid));
2097   if (NULL == ch)
2098   {
2099     GNUNET_STATISTICS_update (stats, "# ack on unknown channel", 1, GNUNET_NO);
2100     return;
2101   }
2102   ack = ntohl (msg->mid);
2103   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! %s ACK %u\n",
2104               (GNUNET_YES == fwd) ? "FWD" : "BCK", ack);
2105
2106   if (GNUNET_YES == fwd)
2107   {
2108     rel = ch->root_rel;
2109   }
2110   else
2111   {
2112     rel = ch->dest_rel;
2113   }
2114   if (NULL == rel)
2115   {
2116     GNUNET_break (0);
2117     return;
2118   }
2119
2120   for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next)
2121   {
2122     if (GMC_is_pid_bigger (copy->mid, ack))
2123     {
2124       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!!  head %u, out!\n", copy->mid);
2125       channel_rel_free_sent (rel, msg);
2126       break;
2127     }
2128     work = GNUNET_YES;
2129     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!!  id %u\n", copy->mid);
2130     next = copy->next;
2131     rel_message_free (copy);
2132   }
2133   /* ACK client if needed */
2134 //   channel_send_ack (t, type, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK == type);
2135
2136   /* If some message was free'd, update the retransmission delay*/
2137   if (GNUNET_YES == work)
2138   {
2139     if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
2140     {
2141       GNUNET_SCHEDULER_cancel (rel->retry_task);
2142       if (NULL == rel->head_sent)
2143       {
2144         rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
2145       }
2146       else
2147       {
2148         struct GNUNET_TIME_Absolute new_target;
2149         struct GNUNET_TIME_Relative delay;
2150
2151         delay = GNUNET_TIME_relative_multiply (rel->retry_timer,
2152                                                MESH_RETRANSMIT_MARGIN);
2153         new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp,
2154                                                delay);
2155         delay = GNUNET_TIME_absolute_get_remaining (new_target);
2156         rel->retry_task =
2157             GNUNET_SCHEDULER_add_delayed (delay,
2158                                           &channel_retransmit_message,
2159                                           rel);
2160       }
2161     }
2162     else
2163       GNUNET_break (0);
2164   }
2165 }
2166
2167
2168
2169
2170 /**
2171  * Handler for channel create messages.
2172  *
2173  * @param t Tunnel this channel is to be created in.
2174  * @param msg Message.
2175  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
2176  */
2177 static void
2178 handle_channel_create (struct MeshTunnel2 *t,
2179                        struct GNUNET_MESH_ChannelCreate *msg,
2180                        int fwd)
2181 {
2182   MESH_ChannelNumber chid;
2183   struct MeshChannel *ch;
2184   struct MeshClient *c;
2185   uint32_t port;
2186
2187   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Channel Create\n");
2188   /* Check message size */
2189   if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelCreate))
2190   {
2191     GNUNET_break_op (0);
2192     return;
2193   }
2194
2195   /* Check if channel exists */
2196   chid = ntohl (msg->chid);
2197   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   chid %u\n", chid);
2198   ch = channel_get (t, chid);
2199   if (NULL != ch)
2200   {
2201     /* Probably a retransmission, safe to ignore */
2202     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   already exists...\n");
2203     if (NULL != ch->dest)
2204     {
2205       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   duplicate CC!!\n");
2206       channel_send_ack (ch, !fwd);
2207       return;
2208     }
2209   }
2210   else
2211   {
2212     /* Create channel */
2213     ch = channel_new (t, NULL, 0);
2214     ch->gid = chid;
2215     channel_set_options (ch, ntohl (msg->opt));
2216   }
2217
2218   /* Find a destination client */
2219   port = ntohl (msg->port);
2220   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   port %u\n", port);
2221   c = GNUNET_CONTAINER_multihashmap32_get (ports, port);
2222   if (NULL == c)
2223   {
2224     /* TODO send reject */
2225     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  no client has port registered\n");
2226     /* TODO free ch */
2227     return;
2228   }
2229
2230   channel_add_client (ch, c);
2231   if (GNUNET_YES == ch->reliable)
2232     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! Reliable\n");
2233
2234   send_local_channel_create (ch);
2235   channel_send_ack (ch, fwd);
2236   send_local_ack (ch, !fwd);
2237 }
2238
2239
2240 /**
2241  * Handler for channel ack messages.
2242  *
2243  * @param t Tunnel this channel is to be created in.
2244  * @param msg Message.
2245  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
2246  */
2247 static void
2248 handle_channel_ack (struct MeshTunnel2 *t,
2249                     struct GNUNET_MESH_ChannelManage *msg,
2250                     int fwd)
2251 {
2252   MESH_ChannelNumber chid;
2253   struct MeshChannel *ch;
2254
2255   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Channel ACK\n");
2256   /* Check message size */
2257   if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage))
2258   {
2259     GNUNET_break_op (0);
2260     return;
2261   }
2262
2263   /* Check if channel exists */
2264   chid = ntohl (msg->chid);
2265   ch = channel_get (t, chid);
2266   if (NULL == ch)
2267   {
2268     GNUNET_break_op (0);
2269     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   channel %u unknown!!\n", chid);
2270     return;
2271   }
2272
2273   channel_confirm (ch, !fwd);
2274 }
2275
2276
2277 /**
2278  * Handler for channel destroy messages.
2279  *
2280  * @param t Tunnel this channel is to be destroyed of.
2281  * @param msg Message.
2282  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
2283  */
2284 static void
2285 handle_channel_destroy (struct MeshTunnel2 *t,
2286                         struct GNUNET_MESH_ChannelManage *msg,
2287                         int fwd)
2288 {
2289   MESH_ChannelNumber chid;
2290   struct MeshChannel *ch;
2291
2292   /* Check message size */
2293   if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage))
2294   {
2295     GNUNET_break_op (0);
2296     return;
2297   }
2298
2299   /* Check if channel exists */
2300   chid = ntohl (msg->chid);
2301   ch = channel_get (t, chid);
2302   if (NULL == ch)
2303   {
2304     /* Probably a retransmission, safe to ignore */
2305     return;
2306   }
2307   if ( (fwd && NULL == ch->dest) || (!fwd && NULL == ch->root) )
2308   {
2309     /* Not for us (don't destroy twice a half-open loopback channel) */
2310     return;
2311   }
2312
2313   send_local_channel_destroy (ch, fwd);
2314   channel_destroy (ch);
2315 }
2316
2317
2318 static void
2319 handle_decrypted (struct MeshTunnel2 *t,
2320                   const struct GNUNET_MessageHeader *msgh,
2321                   int fwd)
2322 {
2323   switch (ntohs (msgh->type))
2324   {
2325     case GNUNET_MESSAGE_TYPE_MESH_DATA:
2326       /* Don't send hop ACK, wait for client to ACK */
2327       handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd);
2328       break;
2329
2330     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
2331       handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd);
2332       break;
2333
2334     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
2335       handle_channel_create (t,
2336                              (struct GNUNET_MESH_ChannelCreate *) msgh,
2337                              fwd);
2338       break;
2339
2340     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
2341       handle_channel_ack (t,
2342                           (struct GNUNET_MESH_ChannelManage *) msgh,
2343                           fwd);
2344       break;
2345
2346     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
2347       handle_channel_destroy (t,
2348                               (struct GNUNET_MESH_ChannelManage *) msgh,
2349                               fwd);
2350       break;
2351
2352     default:
2353       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2354                   "end-to-end message not known (%u)\n",
2355                   ntohs (msgh->type));
2356   }
2357 }
2358
2359
2360 /**
2361  * Function to process paths received for a new peer addition. The recorded
2362  * paths form the initial tunnel, which can be optimized later.
2363  * Called on each result obtained for the DHT search.
2364  *
2365  * @param cls closure
2366  * @param exp when will this value expire
2367  * @param key key of the result
2368  * @param get_path path of the get request
2369  * @param get_path_length lenght of get_path
2370  * @param put_path path of the put request
2371  * @param put_path_length length of the put_path
2372  * @param type type of the result
2373  * @param size number of bytes in data
2374  * @param data pointer to the result data
2375  */
2376 static void
2377 dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
2378                     const struct GNUNET_HashCode * key,
2379                     const struct GNUNET_PeerIdentity *get_path,
2380                     unsigned int get_path_length,
2381                     const struct GNUNET_PeerIdentity *put_path,
2382                     unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
2383                     size_t size, const void *data)
2384 {
2385   struct MeshPeer *peer = cls;
2386   struct MeshPeerPath *p;
2387   struct MeshConnection *c;
2388   struct GNUNET_PeerIdentity pi;
2389   unsigned int connection_count;
2390
2391   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got results from DHT!\n");
2392   GNUNET_PEER_resolve (peer->id, &pi);
2393   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  for %s\n", GNUNET_i2s (&pi));
2394
2395   p = path_build_from_dht (get_path, get_path_length,
2396                            put_path, put_path_length);
2397   path_add_to_peers (p, GNUNET_NO);
2398   path_destroy (p);
2399
2400   /* Count connections */
2401   connection_count = GMC_count (peer->tunnel->connection_head);
2402
2403   /* If we already have 3 (or more (?!)) connections, it's enough */
2404   if (3 <= connection_count)
2405     return;
2406
2407   if (peer->tunnel->state == MESH_TUNNEL_SEARCHING)
2408   {
2409     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... connect!\n");
2410     peer_connect (peer);
2411   }
2412   return;
2413 }
2414
2415
2416
2417 /**
2418  * Method called whenever a given peer connects.
2419  *
2420  * @param cls closure
2421  * @param peer peer identity this notification is about
2422  */
2423 static void
2424 core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
2425 {
2426   struct MeshPeer *pi;
2427   struct MeshPeerPath *path;
2428
2429   DEBUG_CONN ("Peer connected\n");
2430   DEBUG_CONN ("     %s\n", GNUNET_i2s (&my_full_id));
2431   pi = peer_get (peer);
2432   if (myid == pi->id)
2433   {
2434     DEBUG_CONN ("     (self)\n");
2435     path = path_new (1);
2436   }
2437   else
2438   {
2439     DEBUG_CONN ("     %s\n", GNUNET_i2s (peer));
2440     path = path_new (2);
2441     path->peers[1] = pi->id;
2442     GNUNET_PEER_change_rc (pi->id, 1);
2443     GNUNET_STATISTICS_update (stats, "# peers", 1, GNUNET_NO);
2444   }
2445   path->peers[0] = myid;
2446   GNUNET_PEER_change_rc (myid, 1);
2447   peer_add_path (pi, path, GNUNET_YES);
2448
2449   pi->connections = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_YES);
2450   return;
2451 }
2452
2453
2454 /**
2455  * Method called whenever a peer disconnects.
2456  *
2457  * @param cls closure
2458  * @param peer peer identity this notification is about
2459  */
2460 static void
2461 core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
2462 {
2463   struct MeshPeer *pi;
2464
2465   DEBUG_CONN ("Peer disconnected\n");
2466   pi = GNUNET_CONTAINER_multipeermap_get (peers, peer);
2467   if (NULL == pi)
2468   {
2469     GNUNET_break (0);
2470     return;
2471   }
2472
2473   GNUNET_CONTAINER_multihashmap_iterate (pi->connections,
2474                                          GMC_notify_broken,
2475                                          pi);
2476   GNUNET_CONTAINER_multihashmap_destroy (pi->connections);
2477   pi->connections = NULL;
2478   if (NULL != pi->core_transmit)
2479     {
2480       GNUNET_CORE_notify_transmit_ready_cancel (pi->core_transmit);
2481       pi->core_transmit = NULL;
2482     }
2483   if (myid == pi->id)
2484   {
2485     DEBUG_CONN ("     (self)\n");
2486   }
2487   GNUNET_STATISTICS_update (stats, "# peers", -1, GNUNET_NO);
2488
2489   return;
2490 }
2491
2492
2493
2494 /**
2495  * To be called on core init/fail.
2496  *
2497  * @param cls Closure (config)
2498  * @param identity the public identity of this peer
2499  */
2500 static void
2501 core_init (void *cls, 
2502            const struct GNUNET_PeerIdentity *identity)
2503 {
2504   const struct GNUNET_CONFIGURATION_Handle *c = cls;
2505   static int i = 0;
2506
2507   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
2508   if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id)))
2509   {
2510     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
2511     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2512                 " core id %s\n",
2513                 GNUNET_i2s (identity));
2514     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2515                 " my id %s\n",
2516                 GNUNET_i2s (&my_full_id));
2517     GNUNET_CORE_disconnect (core_handle);
2518     core_handle = GNUNET_CORE_connect (c, /* Main configuration */
2519                                        NULL,      /* Closure passed to MESH functions */
2520                                        &core_init,        /* Call core_init once connected */
2521                                        &core_connect,     /* Handle connects */
2522                                        &core_disconnect,  /* remove peers on disconnects */
2523                                        NULL,      /* Don't notify about all incoming messages */
2524                                        GNUNET_NO, /* For header only in notification */
2525                                        NULL,      /* Don't notify about all outbound messages */
2526                                        GNUNET_NO, /* For header-only out notification */
2527                                        core_handlers);    /* Register these handlers */
2528     if (10 < i++)
2529       GNUNET_abort();
2530   }
2531   server_init ();
2532   return;
2533 }
2534
2535
2536 /******************************************************************************/
2537 /************************      MAIN FUNCTIONS      ****************************/
2538 /******************************************************************************/
2539
2540
2541
2542
2543 /**
2544  * Task run during shutdown.
2545  *
2546  * @param cls unused
2547  * @param tc unused
2548  */
2549 static void
2550 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2551 {
2552   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutting down\n");
2553
2554   GML_shutdown ();
2555   GMD_shutdown ();
2556   GMP_shutdown ();
2557   GMC_shutdown ();
2558
2559   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n");
2560 }
2561
2562
2563 /**
2564  * Process mesh requests.
2565  *
2566  * @param cls closure
2567  * @param server the initialized server
2568  * @param c configuration to use
2569  */
2570 static void
2571 run (void *cls, struct GNUNET_SERVER_Handle *server,
2572      const struct GNUNET_CONFIGURATION_Handle *c)
2573 {
2574   struct GNUNET_CRYPTO_EccPrivateKey *pk;
2575
2576   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n");
2577
2578   if (GNUNET_OK !=
2579       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "CONNECT_TIMEOUT",
2580                                            &connect_timeout))
2581   {
2582     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
2583                                "MESH", "CONNECT_TIMEOUT", "MISSING");
2584     GNUNET_SCHEDULER_shutdown ();
2585     return;
2586   }
2587
2588   if (GNUNET_OK !=
2589       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL",
2590                                              &default_ttl))
2591   {
2592     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
2593                                "MESH", "DEFAULT_TTL", "USING DEFAULT");
2594     default_ttl = 64;
2595   }
2596
2597   if (GNUNET_OK !=
2598       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DROP_PERCENT",
2599                                              &drop_percent))
2600   {
2601     drop_percent = 0;
2602   }
2603   else
2604   {
2605     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2606                 "\n***************************************\n"
2607                 "Mesh is running with drop mode enabled.\n"
2608                 "This is NOT a good idea!\n"
2609                 "Remove the DROP_PERCENT option from your configuration.\n"
2610                 "***************************************\n");
2611   }
2612
2613
2614   stats = GNUNET_STATISTICS_create ("mesh", c);
2615
2616   /* Scheduled the task to clean up when shutdown is called */
2617   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
2618                                 NULL);
2619   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "reading key\n");
2620   pk = GNUNET_CRYPTO_ecc_key_create_from_configuration (c);
2621   GNUNET_assert (NULL != pk);
2622   my_private_key = pk;
2623   GNUNET_CRYPTO_ecc_key_get_public_for_signature (my_private_key, 
2624                                                   &my_full_id.public_key);
2625   myid = GNUNET_PEER_intern (&my_full_id);
2626   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2627               "Mesh for peer [%s] starting\n",
2628               GNUNET_i2s(&my_full_id));
2629
2630   GML_init (server);    /* Local clients */
2631   GMC_init (c);         /* Connections */
2632   GMP_init (c);         /* Peers */
2633   GMD_init (c);         /* DHT */
2634
2635   announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
2636   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh service running\n");
2637 }
2638
2639
2640 /**
2641  * The main function for the mesh service.
2642  *
2643  * @param argc number of arguments from the command line
2644  * @param argv command line arguments
2645  * @return 0 ok, 1 on error
2646  */
2647 int
2648 main (int argc, char *const *argv)
2649 {
2650   int ret;
2651   int r;
2652
2653   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main()\n");
2654   r = GNUNET_SERVICE_run (argc, argv, "mesh", GNUNET_SERVICE_OPTION_NONE, &run,
2655                           NULL);
2656   ret = (GNUNET_OK == r) ? 0 : 1;
2657   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main() END\n");
2658
2659   INTERVAL_SHOW;
2660
2661   return ret;
2662 }