more work towards XDG spec (#3000) -- config file location
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh_tunnel.c
1 /*
2      This file is part of GNUnet.
3      (C) 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 #include "platform.h"
22 #include "gnunet_util_lib.h"
23
24 #include "gnunet_statistics_service.h"
25
26 #include "mesh_protocol_enc.h"
27
28 #include "gnunet-service-mesh_tunnel.h"
29 #include "gnunet-service-mesh_connection.h"
30 #include "gnunet-service-mesh_channel.h"
31 #include "gnunet-service-mesh_peer.h"
32 #include "mesh_path.h"
33
34 #define LOG(level, ...) GNUNET_log_from(level,"mesh-tun",__VA_ARGS__)
35
36
37 /******************************************************************************/
38 /********************************   STRUCTS  **********************************/
39 /******************************************************************************/
40
41 struct MeshTChannel
42 {
43   struct MeshTChannel *next;
44   struct MeshTChannel *prev;
45   struct MeshChannel *ch;
46 };
47
48 struct MeshTConnection
49 {
50   struct MeshTConnection *next;
51   struct MeshTConnection *prev;
52   struct MeshConnection *c;
53 };
54
55 /**
56  * Struct containing all information regarding a tunnel to a peer.
57  */
58 struct MeshTunnel3
59 {
60     /**
61      * Endpoint of the tunnel.
62      */
63   struct MeshPeer *peer;
64
65     /**
66      * State of the tunnel.
67      */
68   enum MeshTunnelState state;
69
70   /**
71    * Local peer ephemeral private key
72    */
73   struct GNUNET_CRYPTO_EccPrivateKey *my_eph_key;
74
75   /**
76    * Local peer ephemeral public key
77    */
78   struct GNUNET_CRYPTO_EccPublicSignKey *my_eph;
79
80   /**
81    * Remote peer's public key.
82    */
83   struct GNUNET_CRYPTO_EccPublicSignKey *peers_eph;
84
85   /**
86    * Encryption ("our") key.
87    */
88   struct GNUNET_CRYPTO_SymmetricSessionKey e_key;
89
90   /**
91    * Decryption ("their") key.
92    */
93   struct GNUNET_CRYPTO_SymmetricSessionKey d_key;
94
95   /**
96    * Paths that are actively used to reach the destination peer.
97    */
98   struct MeshTConnection *connection_head;
99   struct MeshTConnection *connection_tail;
100
101   /**
102    * Next connection number.
103    */
104   uint32_t next_cid;
105
106   /**
107    * Channels inside this tunnel.
108    */
109   struct MeshTChannel *channel_head;
110   struct MeshTChannel *channel_tail;
111
112   /**
113    * Channel ID for the next created channel.
114    */
115   MESH_ChannelNumber next_chid;
116
117   /**
118    * Channel ID for the next incoming channel.
119    */
120   MESH_ChannelNumber next_local_chid;
121
122   /**
123    * Pending message count.
124    */
125   int pending_messages;
126
127   /**
128    * Destroy flag: if true, destroy on last message.
129    */
130   int destroy;
131
132   /**
133    * Queued messages, to transmit once tunnel gets connected.
134    */
135   struct MeshTunnelQueue *tq_head;
136   struct MeshTunnelQueue *tq_tail;
137 };
138
139
140 /**
141  * Struct used to queue messages in a tunnel.
142  */
143 struct MeshTunnelQueue
144 {
145   /**
146    * DLL
147    */
148   struct MeshTunnelQueue *next;
149   struct MeshTunnelQueue *prev;
150
151   /**
152    * Channel.
153    */
154   struct MeshChannel *ch;
155
156   /**
157    * Message to send.
158    */
159   /* struct GNUNET_MessageHeader *msg; */
160 };
161
162 /******************************************************************************/
163 /*******************************   GLOBALS  ***********************************/
164 /******************************************************************************/
165
166 /**
167  * Global handle to the statistics service.
168  */
169 extern struct GNUNET_STATISTICS_Handle *stats;
170
171 /**
172  * Default TTL for payload packets.
173  */
174 static unsigned long long default_ttl;
175
176 /**
177  * Local peer own ID (memory efficient handle).
178  */
179 static GNUNET_PEER_Id my_short_id;
180
181 /**
182  * Local peer own ID (full value).
183  */
184 const static struct GNUNET_PeerIdentity *my_full_id;
185
186 /**
187  * Own private key.
188  */
189 const static struct GNUNET_CRYPTO_EccPrivateKey *my_private_key;
190
191
192 /******************************************************************************/
193 /********************************   STATIC  ***********************************/
194 /******************************************************************************/
195
196 /**
197  * Get string description for tunnel state.
198  *
199  * @param s Tunnel state.
200  *
201  * @return String representation.
202  */
203 static const char *
204 GMT_state2s (enum MeshTunnelState s)
205 {
206   static char buf[128];
207
208   switch (s)
209   {
210     case MESH_TUNNEL_NEW:
211       return "MESH_TUNNEL_NEW";
212     case MESH_TUNNEL_SEARCHING:
213       return "MESH_TUNNEL_SEARCHING";
214     case MESH_TUNNEL_WAITING:
215       return "MESH_TUNNEL_WAITING";
216     case MESH_TUNNEL_READY:
217       return "MESH_TUNNEL_READY";
218     case MESH_TUNNEL_RECONNECTING:
219       return "MESH_TUNNEL_RECONNECTING";
220
221     default:
222       sprintf (buf, "%u (UNKNOWN STATE)", s);
223       return buf;
224   }
225 }
226
227
228 /**
229  * Search for a channel by global ID using full PeerIdentities.
230  *
231  * @param t Tunnel containing the channel.
232  * @param chid Public channel number.
233  *
234  * @return channel handler, NULL if doesn't exist
235  */
236 static struct MeshChannel *
237 get_channel (struct MeshTunnel3 *t, MESH_ChannelNumber chid)
238 {
239   struct MeshTChannel *iter;
240
241   if (NULL == t)
242     return NULL;
243
244   for (iter = t->channel_head; NULL != iter; iter = iter->next)
245   {
246     if (GMCH_get_id (iter->ch) == chid)
247       break;
248   }
249
250   return NULL == iter ? NULL : iter->ch;
251 }
252
253
254 /**
255  * Pick a connection on which send the next data message.
256  *
257  * @param t Tunnel on which to send the message.
258  * @param fwd Is this a fwd message?
259  *
260  * @return The connection on which to send the next message.
261  */
262 static struct MeshConnection *
263 tunnel_get_connection (struct MeshTunnel3 *t, int fwd)
264 {
265   struct MeshTConnection *iter;
266   struct MeshConnection *best;
267   unsigned int qn;
268   unsigned int lowest_q;
269
270   LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n", GMP_2s (t->peer));
271   best = NULL;
272   lowest_q = UINT_MAX;
273   for (iter = t->connection_head; NULL != iter; iter = iter->next)
274   {
275     LOG (GNUNET_ERROR_TYPE_DEBUG, "  connection %s: %u\n",
276          GNUNET_h2s (GMC_get_id (iter->c)), GMC_get_state (iter->c));
277     if (MESH_CONNECTION_READY == GMC_get_state (iter->c))
278     {
279       qn = GMC_get_qn (iter->c, fwd);
280       LOG (GNUNET_ERROR_TYPE_DEBUG, "    q_n %u, \n", qn);
281       if (qn < lowest_q)
282       {
283         best = iter->c;
284         lowest_q = qn;
285       }
286     }
287   }
288   return best;
289 }
290
291
292 void
293 handle_data (struct MeshTunnel3 *t,
294              const struct GNUNET_MESH_Data *msg,
295              int fwd)
296 {
297   struct MeshChannel *ch;
298   uint16_t type;
299   size_t size;
300
301   /* Check size */
302   size = ntohs (msg->header.size);
303   if (size <
304       sizeof (struct GNUNET_MESH_Data) +
305       sizeof (struct GNUNET_MessageHeader))
306   {
307     GNUNET_break (0);
308     return;
309   }
310   type = ntohs (msg->header.type);
311   LOG (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n",
312               GNUNET_MESH_DEBUG_M2S (type));
313   LOG (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n",
314               GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
315
316   /* Check channel */
317   ch = get_channel (t, ntohl (msg->chid));
318   if (NULL == ch)
319   {
320     GNUNET_STATISTICS_update (stats, "# data on unknown channel",
321                               1, GNUNET_NO);
322     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
323          ntohl (msg->chid));
324     return;
325   }
326
327   GMT_change_state (t, MESH_TUNNEL_READY);
328   GMCH_handle_data (ch, msg, fwd);
329 }
330
331 void
332 handle_data_ack (struct MeshTunnel3 *t,
333                  const struct GNUNET_MESH_DataACK *msg,
334                  int fwd)
335 {
336   struct MeshChannel *ch;
337   size_t size;
338
339   /* Check size */
340   size = ntohs (msg->header.size);
341   if (size != sizeof (struct GNUNET_MESH_DataACK))
342   {
343     GNUNET_break (0);
344     return;
345   }
346
347   /* Check channel */
348   ch = get_channel (t, ntohl (msg->chid));
349   if (NULL == ch)
350   {
351     GNUNET_STATISTICS_update (stats, "# data ack on unknown channel",
352                               1, GNUNET_NO);
353     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
354          ntohl (msg->chid));
355     return;
356   }
357
358   GMCH_handle_data_ack (ch, msg, fwd);
359 }
360
361 void
362 handle_ch_create (struct MeshTunnel3 *t,
363                   const struct GNUNET_MESH_ChannelCreate *msg,
364                   int fwd)
365 {
366   struct MeshTChannel *tch;
367   struct MeshChannel *ch;
368   size_t size;
369
370   /* Check size */
371   size = ntohs (msg->header.size);
372   if (size != sizeof (struct GNUNET_MESH_ChannelCreate))
373   {
374     GNUNET_break (0);
375     return;
376   }
377
378   /* Check channel */
379   ch = get_channel (t, ntohl (msg->chid));
380   if (NULL != ch)
381   {
382     /* Probably a retransmission, safe to ignore */
383     LOG (GNUNET_ERROR_TYPE_DEBUG, "   already exists...\n");
384   }
385   else
386   {
387     ch = GMCH_handle_create (msg, fwd);
388   }
389
390   tch = GNUNET_new (struct MeshTChannel);
391   tch->ch = ch;
392   GNUNET_CONTAINER_DLL_insert (t->channel_head, t->channel_tail, tch);
393 }
394
395 void
396 handle_ch_ack (struct MeshTunnel3 *t,
397                const struct GNUNET_MESH_ChannelManage *msg,
398                int fwd)
399 {
400   struct MeshChannel *ch;
401   size_t size;
402
403   /* Check size */
404   size = ntohs (msg->header.size);
405   if (size != sizeof (struct GNUNET_MESH_ChannelManage))
406   {
407     GNUNET_break (0);
408     return;
409   }
410
411   /* Check channel */
412   ch = get_channel (t, ntohl (msg->chid));
413   if (NULL == ch)
414   {
415     GNUNET_STATISTICS_update (stats, "# channel ack on unknown channel",
416                               1, GNUNET_NO);
417     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
418          ntohl (msg->chid));
419     return;
420   }
421
422   GMCH_handle_ack (ch, msg, fwd);
423 }
424
425 void
426 handle_ch_destroy (struct MeshTunnel3 *t,
427                    const struct GNUNET_MESH_ChannelManage *msg,
428                    int fwd)
429 {
430   struct MeshChannel *ch;
431   size_t size;
432
433   /* Check size */
434   size = ntohs (msg->header.size);
435   if (size != sizeof (struct GNUNET_MESH_ChannelManage))
436   {
437     GNUNET_break (0);
438     return;
439   }
440
441   /* Check channel */
442   ch = get_channel (t, ntohl (msg->chid));
443   if (NULL == ch)
444   {
445     /* Probably a retransmission, safe to ignore */
446     return;
447   }
448
449   GMCH_handle_destroy (ch, msg, fwd);
450 }
451
452 /******************************************************************************/
453 /********************************    API    ***********************************/
454 /******************************************************************************/
455
456 /**
457  * Demultiplex by message type and call appropriate handler for a message
458  * towards a channel of a local tunnel.
459  *
460  * @param t Tunnel this message came on.
461  * @param msgh Message header.
462  * @param fwd Is this message fwd?
463  */
464 void
465 GMT_handle_decrypted (struct MeshTunnel3 *t,
466                       const struct GNUNET_MessageHeader *msgh,
467                       int fwd)
468 {
469   uint16_t type;
470
471   type = ntohs (msgh->type);
472   LOG (GNUNET_ERROR_TYPE_DEBUG,
473        "Got a %s message!\n",
474        GNUNET_MESH_DEBUG_M2S (type));
475
476   switch (type)
477   {
478     case GNUNET_MESSAGE_TYPE_MESH_DATA:
479       /* Don't send hop ACK, wait for client to ACK */
480       handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd);
481       break;
482
483     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
484       handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd);
485       break;
486
487     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
488       handle_ch_create (t,
489                         (struct GNUNET_MESH_ChannelCreate *) msgh,
490                         fwd);
491       break;
492
493     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
494       handle_ch_ack (t,
495                      (struct GNUNET_MESH_ChannelManage *) msgh,
496                      fwd);
497       break;
498
499     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
500       handle_ch_destroy (t,
501                          (struct GNUNET_MESH_ChannelManage *) msgh,
502                          fwd);
503       break;
504
505     default:
506       GNUNET_break_op (0);
507       LOG (GNUNET_ERROR_TYPE_DEBUG,
508            "end-to-end message not known (%u)\n",
509            ntohs (msgh->type));
510   }
511 }
512
513
514 /**
515  * Cache a message to be sent once tunnel is online.
516  *
517  * @param t Tunnel to hold the message.
518  * @param ch Channel the message is about.
519  * @param msg Message itself (copy will be made).
520  * @param fwd Is this fwd?
521  */
522 void
523 GMT_queue_data (struct MeshTunnel3 *t,
524                 struct MeshChannel *ch,
525                 struct GNUNET_MessageHeader *msg,
526                 int fwd)
527 {
528   struct MeshTunnelQueue *tq;
529   uint16_t size = ntohs (msg->size);
530
531   tq = GNUNET_malloc (sizeof (struct MeshTunnelQueue) + size);
532
533   tq->ch = ch;
534   memcpy (&tq[1], msg, size);
535   GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tq);
536
537   if (MESH_TUNNEL_READY == t->state)
538     GMT_send_queued_data (t, fwd);
539 }
540
541
542 /**
543  * Send all cached messages that we can, tunnel is online.
544  *
545  * @param t Tunnel that holds the messages.
546  * @param fwd Is this fwd?
547  */
548 void
549 GMT_send_queued_data (struct MeshTunnel3 *t, int fwd)
550 {
551   struct MeshTunnelQueue *tq;
552   struct MeshTunnelQueue *next;
553   unsigned int room;
554
555   LOG (GNUNET_ERROR_TYPE_DEBUG,
556               "GMT_send_queued_data on tunnel %s\n",
557               GMP_2s (t->peer));
558   room = GMT_get_buffer (t, fwd);
559   LOG (GNUNET_ERROR_TYPE_DEBUG, "  buffer space: %u\n", room);
560   for (tq = t->tq_head; NULL != tq && room > 0; tq = next)
561   {
562     next = tq->next;
563     room--;
564     GNUNET_CONTAINER_DLL_remove (t->tq_head, t->tq_tail, tq);
565     GMCH_send_prebuilt_message ((struct GNUNET_MessageHeader *) &tq[1],
566                                 tq->ch, fwd);
567
568     GNUNET_free (tq);
569   }
570 }
571
572
573 /**
574  * Initialize the tunnel subsystem.
575  *
576  * @param c Configuration handle.
577  * @param id Peer identity.
578  * @param key ECC private key, to derive all other keys and do crypto.
579  */
580 void
581 GMT_init (const struct GNUNET_CONFIGURATION_Handle *c,
582           const struct GNUNET_PeerIdentity *id,
583           const struct GNUNET_CRYPTO_EccPrivateKey *key)
584 {
585   if (GNUNET_OK !=
586       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL",
587                                              &default_ttl))
588   {
589     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
590                                "MESH", "DEFAULT_TTL", "USING DEFAULT");
591     default_ttl = 64;
592   }
593   my_full_id = id;
594   my_private_key = key;
595   my_short_id = GNUNET_PEER_intern (my_full_id);
596 }
597
598
599 /**
600  * Shut down the tunnel subsystem.
601  */
602 void
603 GMT_shutdown (void)
604 {
605   GNUNET_PEER_change_rc (my_short_id, -1);
606 }
607
608
609 /**
610  * Create a tunnel.
611  */
612 struct MeshTunnel3 *
613 GMT_new (void)
614 {
615   struct MeshTunnel3 *t;
616
617   t = GNUNET_new (struct MeshTunnel3);
618   t->next_chid = 0;
619   t->next_local_chid = GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
620 //   if (GNUNET_OK !=
621 //       GNUNET_CONTAINER_multihashmap_put (tunnels, tid, t,
622 //                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
623 //   {
624 //     GNUNET_break (0);
625 //     tunnel_destroy (t);
626 //     return NULL;
627 //   }
628
629 //   char salt[] = "salt";
630 //   GNUNET_CRYPTO_kdf (&t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
631 //                      salt, sizeof (salt),
632 //                      &t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
633 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
634 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
635 //                      NULL);
636 //   GNUNET_CRYPTO_kdf (&t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
637 //                      salt, sizeof (salt),
638 //                      &t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
639 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
640 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
641 //                      NULL);
642
643   return t;
644 }
645
646
647
648 /**
649  * Change the tunnel state.
650  *
651  * @param t Tunnel whose state to change.
652  * @param state New state.
653  */
654 void
655 GMT_change_state (struct MeshTunnel3* t, enum MeshTunnelState state)
656 {
657   if (NULL == t)
658     return;
659   LOG (GNUNET_ERROR_TYPE_DEBUG,
660               "Tunnel %s state was %s\n",
661               GMP_2s (t->peer),
662               GMT_state2s (t->state));
663   LOG (GNUNET_ERROR_TYPE_DEBUG,
664               "Tunnel %s state is now %s\n",
665               GMP_2s (t->peer),
666               GMT_state2s (state));
667   t->state = state;
668 }
669
670
671 /**
672  * Add a connection to a tunnel.
673  *
674  * @param t Tunnel.
675  * @param c Connection.
676  */
677 void
678 GMT_add_connection (struct MeshTunnel3 *t, struct MeshConnection *c)
679 {
680   struct MeshTConnection *aux;
681
682   for (aux = t->connection_head; aux != NULL; aux = aux->next)
683     if (aux->c == c)
684       return;
685
686   aux = GNUNET_new (struct MeshTConnection);
687   aux->c = c;
688   GNUNET_CONTAINER_DLL_insert_tail (t->connection_head, t->connection_tail, aux);
689 }
690
691
692 /**
693  * Remove a connection from a tunnel.
694  *
695  * @param t Tunnel.
696  * @param c Connection.
697  */
698 void
699 GMT_remove_connection (struct MeshTunnel3 *t, struct MeshConnection *c)
700 {
701   struct MeshTConnection *aux;
702
703   for (aux = t->connection_head; aux != NULL; aux = aux->next)
704     if (aux->c == c)
705     {
706       GNUNET_CONTAINER_DLL_remove (t->connection_head, t->connection_tail, aux);
707       GNUNET_free (aux);
708       return;
709     }
710 }
711
712
713 /**
714  * Tunnel is empty: destroy it.
715  *
716  * Notifies all connections about the destruction.
717  *
718  * @param t Tunnel to destroy.
719  */
720 void
721 GMT_destroy_empty (struct MeshTunnel3 *t)
722 {
723   struct MeshTConnection *iter;
724
725   for (iter = t->connection_head; NULL != iter; iter = iter->next)
726   {
727     GMC_send_destroy (iter->c);
728   }
729
730   if (0 == t->pending_messages)
731     GMT_destroy (t);
732   else
733     t->destroy = GNUNET_YES;
734 }
735
736
737 /**
738  * Destroy tunnel if empty (no more channels).
739  *
740  * @param t Tunnel to destroy if empty.
741  */
742 void
743 GMT_destroy_if_empty (struct MeshTunnel3 *t)
744 {
745   if (1 < GMT_count_channels (t))
746     return;
747
748   GMT_destroy_empty (t);
749 }
750
751
752 /**
753  * Destroy the tunnel.
754  *
755  * This function does not generate any warning traffic to clients or peers.
756  *
757  * Tasks:
758  * Cancel messages belonging to this tunnel queued to neighbors.
759  * Free any allocated resources linked to the tunnel.
760  *
761  * @param t The tunnel to destroy.
762  */
763 void
764 GMT_destroy (struct MeshTunnel3 *t)
765 {
766   struct MeshTConnection *iter;
767   struct MeshTConnection *next;
768
769   if (NULL == t)
770     return;
771
772   LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n", GMP_2s (t->peer));
773
774 //   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &t->id, t))
775 //     GNUNET_break (0);
776
777   for (iter = t->connection_head; NULL != iter; iter = next)
778   {
779     next = iter->next;
780     GMC_destroy (iter->c);
781     GNUNET_free (iter);
782   }
783
784   GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
785   GMP_set_tunnel (t->peer, NULL);
786
787   GNUNET_free (t);
788 }
789
790
791 /**
792  * Notifies a tunnel that a connection has broken that affects at least
793  * some of its peers. Sends a notification towards the root of the tree.
794  * In case the peer is the owner of the tree, notifies the client that owns
795  * the tunnel and tries to reconnect.
796  *
797  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
798  *
799  * @param t Tunnel affected.
800  * @param p1 Peer that got disconnected from p2.
801  * @param p2 Peer that got disconnected from p1.
802  *
803  * @return Short ID of the peer disconnected (either p1 or p2).
804  *         0 if the tunnel remained unaffected.
805  */
806 GNUNET_PEER_Id
807 GMT_notify_connection_broken (struct MeshTunnel3* t,
808                               GNUNET_PEER_Id p1, GNUNET_PEER_Id p2)
809 {
810 //   if (myid != p1 && myid != p2) FIXME
811 //   {
812 //     return;
813 //   }
814 //
815 //   if (tree_get_predecessor (t->tree) != 0)
816 //   {
817 //     /* We are the peer still connected, notify owner of the disconnection. */
818 //     struct GNUNET_MESH_PathBroken msg;
819 //     struct GNUNET_PeerIdentity neighbor;
820 //
821 //     msg.header.size = htons (sizeof (msg));
822 //     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
823 //     GNUNET_PEER_resolve (t->id.oid, &msg.oid);
824 //     msg.tid = htonl (t->id.tid);
825 //     msg.peer1 = my_full_id;
826 //     GNUNET_PEER_resolve (pid, &msg.peer2);
827 //     GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
828 //     send_prebuilt_message (&msg.header, &neighbor, t);
829 //   }
830   return 0;
831 }
832
833 /**
834  * @brief Use the given path for the tunnel.
835  * Update the next and prev hops (and RCs).
836  * (Re)start the path refresh in case the tunnel is locally owned.
837  *
838  * @param t Tunnel to update.
839  * @param p Path to use.
840  *
841  * @return Connection created.
842  */
843 struct MeshConnection *
844 GMT_use_path (struct MeshTunnel3 *t, struct MeshPeerPath *p)
845 {
846   struct MeshConnection *c;
847   struct GNUNET_HashCode cid;
848   unsigned int own_pos;
849
850   if (NULL == t || NULL == p)
851   {
852     GNUNET_break (0);
853     return NULL;
854   }
855
856   for (own_pos = 0; own_pos < p->length; own_pos++)
857   {
858     if (p->peers[own_pos] == my_short_id)
859       break;
860   }
861   if (own_pos > p->length - 1)
862   {
863     GNUNET_break (0);
864     return NULL;
865   }
866
867   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, &cid);
868   c = GMC_new (&cid, t, p, own_pos);
869   GMT_add_connection (t, c);
870   return c;
871 }
872
873
874 /**
875  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
876  * Encrypt data with the tunnel key.
877  *
878  * @param t Tunnel whose key to use.
879  * @param dst Destination for the encrypted data.
880  * @param src Source of the plaintext.
881  * @param size Size of the plaintext.
882  * @param iv Initialization Vector to use.
883  * @param fwd Is this a fwd message?
884  */
885 void
886 GMT_encrypt (struct MeshTunnel3 *t,
887              void *dst, const void *src,
888              size_t size, uint64_t iv, int fwd)
889 {
890   memcpy (dst, src, size);
891 }
892
893
894 /**
895  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
896  * Decrypt data with the tunnel key.
897  *
898  * @param t Tunnel whose key to use.
899  * @param dst Destination for the plaintext.
900  * @param src Source of the encrypted data.
901  * @param size Size of the encrypted data.
902  * @param iv Initialization Vector to use.
903  * @param fwd Is this a fwd message?
904  */
905 void
906 GMT_decrypt (struct MeshTunnel3 *t,
907              void *dst, const void *src,
908              size_t size, uint64_t iv, int fwd)
909 {
910   memcpy (dst, src, size);
911 }
912
913
914 /**
915  * Count established (ready) connections of a tunnel.
916  *
917  * @param t Tunnel on which to count.
918  *
919  * @return Number of connections.
920  */
921 unsigned int
922 GMT_count_connections (struct MeshTunnel3 *t)
923 {
924   struct MeshTConnection *iter;
925   unsigned int count;
926
927   for (count = 0, iter = t->connection_head;
928        NULL != iter;
929        iter = iter->next, count++);
930
931   return count;
932 }
933
934 /**
935  * Count channels of a tunnel.
936  *
937  * @param t Tunnel on which to count.
938  *
939  * @return Number of channels.
940  */
941 unsigned int
942 GMT_count_channels (struct MeshTunnel3 *t)
943 {
944   struct MeshTChannel *iter;
945   unsigned int count;
946
947   for (count = 0, iter = t->channel_head;
948        NULL != iter;
949   iter = iter->next, count++);
950
951   return count;
952 }
953
954
955 /**
956  * Get the state of a tunnel.
957  *
958  * @param t Tunnel.
959  *
960  * @return Tunnel's state.
961  */
962 enum MeshTunnelState
963 GMT_get_state (struct MeshTunnel3 *t)
964 {
965   return t->state;
966 }
967
968 /**
969  * Get the total buffer space for a tunnel.
970  *
971  * @param t Tunnel.
972  * @param fwd Is this for FWD traffic?
973  *
974  * @return Buffer space offered by all connections in the tunnel.
975  */
976 unsigned int
977 GMT_get_buffer (struct MeshTunnel3 *t, int fwd)
978 {
979   struct MeshTConnection *iter;
980   unsigned int buffer;
981
982   iter = t->connection_head;
983   buffer = 0;
984
985   /* If terminal, return biggest channel buffer */
986   if (NULL == iter || GMC_is_terminal (iter->c, fwd))
987   {
988     struct MeshTChannel *iter_ch;
989     unsigned int ch_buf;
990
991     if (NULL == t->channel_head)
992       return 64;
993
994     for (iter_ch = t->channel_head; NULL != iter_ch; iter_ch = iter_ch->next)
995     {
996       ch_buf = GMCH_get_buffer (iter_ch->ch, fwd);
997       if (ch_buf > buffer)
998         buffer = ch_buf;
999     }
1000     return buffer;
1001   }
1002
1003   /* If not terminal, return sum of connection buffers */
1004   while (NULL != iter)
1005   {
1006     if (GMC_get_state (iter->c) != MESH_CONNECTION_READY)
1007     {
1008       iter = iter->next;
1009       continue;
1010     }
1011
1012     buffer += GMC_get_buffer (iter->c, fwd);
1013     iter = iter->next;
1014   }
1015
1016   return buffer;
1017 }
1018
1019 /**
1020  * Sends an already built message on a tunnel, choosing the best connection.
1021  *
1022  * @param message Message to send. Function modifies it.
1023  * @param t Tunnel on which this message is transmitted.
1024  * @param ch Channel on which this message is transmitted.
1025  * @param fwd Is this a fwd message?
1026  */
1027 void
1028 GMT_send_prebuilt_message (struct GNUNET_MESH_Encrypted *msg,
1029                            struct MeshTunnel3 *t,
1030                            struct MeshChannel *ch,
1031                            int fwd)
1032 {
1033   struct MeshConnection *c;
1034   uint16_t type;
1035
1036   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n", GMP_2s (t->peer));
1037   c = tunnel_get_connection (t, fwd);
1038   if (NULL == c)
1039   {
1040     GNUNET_break (GNUNET_YES == t->destroy);
1041     return;
1042   }
1043   type = ntohs (msg->header.type);
1044   switch (type)
1045   {
1046     case GNUNET_MESSAGE_TYPE_MESH_FWD:
1047     case GNUNET_MESSAGE_TYPE_MESH_BCK:
1048     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
1049     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
1050       msg->cid = *GMC_get_id (c);
1051       msg->ttl = htonl (default_ttl);
1052       break;
1053     default:
1054       LOG (GNUNET_ERROR_TYPE_DEBUG, "unkown type %s\n",
1055            GNUNET_MESH_DEBUG_M2S (type));
1056       GNUNET_break (0);
1057   }
1058   msg->reserved = 0;
1059
1060   GMC_send_prebuilt_message (&msg->header, c, ch, fwd);
1061 }