8a240f4a88cea0f9a6b200ed8842b072bfac6f06
[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 /**
293  * Send all cached messages that we can, tunnel is online.
294  *
295  * @param t Tunnel that holds the messages.
296  * @param fwd Is this fwd?
297  */
298 static void
299 tunnel_send_queued_data (struct MeshTunnel3 *t, int fwd)
300 {
301   struct MeshTunnelQueue *tq;
302   struct MeshTunnelQueue *next;
303   unsigned int room;
304
305   LOG (GNUNET_ERROR_TYPE_DEBUG,
306               "tunnel_send_queued_data on tunnel %s\n",
307               GMP_2s (t->peer));
308   room = GMT_get_buffer (t, fwd);
309   LOG (GNUNET_ERROR_TYPE_DEBUG, "  buffer space: %u\n", room);
310   for (tq = t->tq_head; NULL != tq && room > 0; tq = next)
311   {
312     next = tq->next;
313     room--;
314     GNUNET_CONTAINER_DLL_remove (t->tq_head, t->tq_tail, tq);
315     GMCH_send_prebuilt_message ((struct GNUNET_MessageHeader *) &tq[1],
316                                 tq->ch, fwd);
317
318     GNUNET_free (tq);
319   }
320 }
321
322 void
323 handle_data (struct MeshTunnel3 *t,
324              const struct GNUNET_MESH_Data *msg,
325              int fwd)
326 {
327   struct MeshChannel *ch;
328   uint16_t type;
329   size_t size;
330
331   /* Check size */
332   size = ntohs (msg->header.size);
333   if (size <
334       sizeof (struct GNUNET_MESH_Data) +
335       sizeof (struct GNUNET_MessageHeader))
336   {
337     GNUNET_break (0);
338     return;
339   }
340   type = ntohs (msg->header.type);
341   LOG (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n",
342               GNUNET_MESH_DEBUG_M2S (type));
343   LOG (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n",
344               GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
345
346   /* Check channel */
347   ch = get_channel (t, ntohl (msg->chid));
348   if (NULL == ch)
349   {
350     GNUNET_STATISTICS_update (stats, "# data on unknown channel",
351                               1, GNUNET_NO);
352     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
353          ntohl (msg->chid));
354     return;
355   }
356
357   GMT_change_state (t, MESH_TUNNEL_READY);
358   GMCH_handle_data (ch, msg, fwd);
359 }
360
361 void
362 handle_data_ack (struct MeshTunnel3 *t,
363                  const struct GNUNET_MESH_DataACK *msg,
364                  int fwd)
365 {
366   struct MeshChannel *ch;
367   size_t size;
368
369   /* Check size */
370   size = ntohs (msg->header.size);
371   if (size != sizeof (struct GNUNET_MESH_DataACK))
372   {
373     GNUNET_break (0);
374     return;
375   }
376
377   /* Check channel */
378   ch = get_channel (t, ntohl (msg->chid));
379   if (NULL == ch)
380   {
381     GNUNET_STATISTICS_update (stats, "# data ack on unknown channel",
382                               1, GNUNET_NO);
383     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
384          ntohl (msg->chid));
385     return;
386   }
387
388   GMCH_handle_data_ack (ch, msg, fwd);
389 }
390
391 void
392 handle_ch_create (struct MeshTunnel3 *t,
393                   const struct GNUNET_MESH_ChannelCreate *msg,
394                   int fwd)
395 {
396   struct MeshTChannel *tch;
397   struct MeshChannel *ch;
398   size_t size;
399
400   /* Check size */
401   size = ntohs (msg->header.size);
402   if (size != sizeof (struct GNUNET_MESH_ChannelCreate))
403   {
404     GNUNET_break (0);
405     return;
406   }
407
408   /* Check channel */
409   ch = get_channel (t, ntohl (msg->chid));
410   if (NULL != ch)
411   {
412     /* Probably a retransmission, safe to ignore */
413     LOG (GNUNET_ERROR_TYPE_DEBUG, "   already exists...\n");
414   }
415   else
416   {
417     ch = GMCH_handle_create (msg, fwd);
418   }
419
420   tch = GNUNET_new (struct MeshTChannel);
421   tch->ch = ch;
422   GNUNET_CONTAINER_DLL_insert (t->channel_head, t->channel_tail, tch);
423 }
424
425 void
426 handle_ch_ack (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     GNUNET_STATISTICS_update (stats, "# channel ack on unknown channel",
446                               1, GNUNET_NO);
447     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
448          ntohl (msg->chid));
449     return;
450   }
451
452   GMCH_handle_ack (ch, msg, fwd);
453 }
454
455 void
456 handle_ch_destroy (struct MeshTunnel3 *t,
457                    const struct GNUNET_MESH_ChannelManage *msg,
458                    int fwd)
459 {
460   struct MeshChannel *ch;
461   size_t size;
462
463   /* Check size */
464   size = ntohs (msg->header.size);
465   if (size != sizeof (struct GNUNET_MESH_ChannelManage))
466   {
467     GNUNET_break (0);
468     return;
469   }
470
471   /* Check channel */
472   ch = get_channel (t, ntohl (msg->chid));
473   if (NULL == ch)
474   {
475     /* Probably a retransmission, safe to ignore */
476     return;
477   }
478
479   GMCH_handle_destroy (ch, msg, fwd);
480 }
481
482 /******************************************************************************/
483 /********************************    API    ***********************************/
484 /******************************************************************************/
485
486 /**
487  * Demultiplex by message type and call appropriate handler for a message
488  * towards a channel of a local tunnel.
489  *
490  * @param t Tunnel this message came on.
491  * @param msgh Message header.
492  * @param fwd Is this message fwd?
493  */
494 void
495 GMT_handle_decrypted (struct MeshTunnel3 *t,
496                       const struct GNUNET_MessageHeader *msgh,
497                       int fwd)
498 {
499   uint16_t type;
500
501   type = ntohs (msgh->type);
502   LOG (GNUNET_ERROR_TYPE_DEBUG,
503        "Got a %s message!\n",
504        GNUNET_MESH_DEBUG_M2S (type));
505
506   switch (type)
507   {
508     case GNUNET_MESSAGE_TYPE_MESH_DATA:
509       /* Don't send hop ACK, wait for client to ACK */
510       handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd);
511       break;
512
513     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
514       handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd);
515       break;
516
517     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
518       handle_ch_create (t,
519                         (struct GNUNET_MESH_ChannelCreate *) msgh,
520                         fwd);
521       break;
522
523     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
524       handle_ch_ack (t,
525                      (struct GNUNET_MESH_ChannelManage *) msgh,
526                      fwd);
527       break;
528
529     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
530       handle_ch_destroy (t,
531                          (struct GNUNET_MESH_ChannelManage *) msgh,
532                          fwd);
533       break;
534
535     default:
536       GNUNET_break_op (0);
537       LOG (GNUNET_ERROR_TYPE_DEBUG,
538            "end-to-end message not known (%u)\n",
539            ntohs (msgh->type));
540   }
541 }
542
543
544 /**
545  * Cache a message to be sent once tunnel is online.
546  *
547  * @param t Tunnel to hold the message.
548  * @param ch Channel the message is about.
549  * @param msg Message itself (copy will be made).
550  * @param fwd Is this fwd?
551  */
552 void
553 GMT_queue_data (struct MeshTunnel3 *t,
554                 struct MeshChannel *ch,
555                 struct GNUNET_MessageHeader *msg,
556                 int fwd)
557 {
558   struct MeshTunnelQueue *tq;
559   uint16_t size = ntohs (msg->size);
560
561   tq = GNUNET_malloc (sizeof (struct MeshTunnelQueue) + size);
562
563   tq->ch = ch;
564   memcpy (&tq[1], msg, size);
565   GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tq);
566
567   if (MESH_TUNNEL_READY == t->state)
568     tunnel_send_queued_data (t, fwd);
569 }
570
571
572 /**
573  * Initialize the tunnel subsystem.
574  *
575  * @param c Configuration handle.
576  * @param id Peer identity.
577  * @param key ECC private key, to derive all other keys and do crypto.
578  */
579 void
580 GMT_init (const struct GNUNET_CONFIGURATION_Handle *c,
581           const struct GNUNET_PeerIdentity *id,
582           const struct GNUNET_CRYPTO_EccPrivateKey *key)
583 {
584   if (GNUNET_OK !=
585       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL",
586                                              &default_ttl))
587   {
588     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
589                                "MESH", "DEFAULT_TTL", "USING DEFAULT");
590     default_ttl = 64;
591   }
592   my_full_id = id;
593   my_private_key = key;
594   my_short_id = GNUNET_PEER_intern (my_full_id);
595 }
596
597
598 /**
599  * Shut down the tunnel subsystem.
600  */
601 void
602 GMT_shutdown (void)
603 {
604   GNUNET_PEER_change_rc (my_short_id, -1);
605 }
606
607
608 /**
609  * Create a tunnel.
610  */
611 struct MeshTunnel3 *
612 GMT_new (void)
613 {
614   struct MeshTunnel3 *t;
615
616   t = GNUNET_new (struct MeshTunnel3);
617   t->next_chid = 0;
618   t->next_local_chid = GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
619 //   if (GNUNET_OK !=
620 //       GNUNET_CONTAINER_multihashmap_put (tunnels, tid, t,
621 //                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
622 //   {
623 //     GNUNET_break (0);
624 //     tunnel_destroy (t);
625 //     return NULL;
626 //   }
627
628 //   char salt[] = "salt";
629 //   GNUNET_CRYPTO_kdf (&t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
630 //                      salt, sizeof (salt),
631 //                      &t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
632 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
633 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
634 //                      NULL);
635 //   GNUNET_CRYPTO_kdf (&t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
636 //                      salt, sizeof (salt),
637 //                      &t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
638 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
639 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
640 //                      NULL);
641
642   return t;
643 }
644
645
646
647 /**
648  * Change the tunnel state.
649  *
650  * @param t Tunnel whose state to change.
651  * @param state New state.
652  */
653 void
654 GMT_change_state (struct MeshTunnel3* t, enum MeshTunnelState state)
655 {
656   if (NULL == t)
657     return;
658   LOG (GNUNET_ERROR_TYPE_DEBUG,
659               "Tunnel %s state was %s\n",
660               GMP_2s (t->peer),
661               GMT_state2s (t->state));
662   LOG (GNUNET_ERROR_TYPE_DEBUG,
663               "Tunnel %s state is now %s\n",
664               GMP_2s (t->peer),
665               GMT_state2s (state));
666   t->state = state;
667 }
668
669
670 /**
671  * Add a connection to a tunnel.
672  *
673  * @param t Tunnel.
674  * @param c Connection.
675  */
676 void
677 GMT_add_connection (struct MeshTunnel3 *t, struct MeshConnection *c)
678 {
679   struct MeshTConnection *aux;
680
681   for (aux = t->connection_head; aux != NULL; aux = aux->next)
682     if (aux->c == c)
683       return;
684
685   aux = GNUNET_new (struct MeshTConnection);
686   aux->c = c;
687   GNUNET_CONTAINER_DLL_insert_tail (t->connection_head, t->connection_tail, aux);
688 }
689
690
691 /**
692  * Remove a connection from a tunnel.
693  *
694  * @param t Tunnel.
695  * @param c Connection.
696  */
697 void
698 GMT_remove_connection (struct MeshTunnel3 *t, struct MeshConnection *c)
699 {
700   struct MeshTConnection *aux;
701
702   for (aux = t->connection_head; aux != NULL; aux = aux->next)
703     if (aux->c == c)
704     {
705       GNUNET_CONTAINER_DLL_remove (t->connection_head, t->connection_tail, aux);
706       GNUNET_free (aux);
707       return;
708     }
709 }
710
711
712 /**
713  * Tunnel is empty: destroy it.
714  *
715  * Notifies all connections about the destruction.
716  *
717  * @param t Tunnel to destroy.
718  */
719 void
720 GMT_destroy_empty (struct MeshTunnel3 *t)
721 {
722   struct MeshTConnection *iter;
723
724   for (iter = t->connection_head; NULL != iter; iter = iter->next)
725   {
726     GMC_send_destroy (iter->c);
727   }
728
729   if (0 == t->pending_messages)
730     GMT_destroy (t);
731   else
732     t->destroy = GNUNET_YES;
733 }
734
735
736 /**
737  * Destroy tunnel if empty (no more channels).
738  *
739  * @param t Tunnel to destroy if empty.
740  */
741 void
742 GMT_destroy_if_empty (struct MeshTunnel3 *t)
743 {
744   if (1 < GMT_count_channels (t))
745     return;
746
747   GMT_destroy_empty (t);
748 }
749
750
751 /**
752  * Destroy the tunnel.
753  *
754  * This function does not generate any warning traffic to clients or peers.
755  *
756  * Tasks:
757  * Cancel messages belonging to this tunnel queued to neighbors.
758  * Free any allocated resources linked to the tunnel.
759  *
760  * @param t The tunnel to destroy.
761  */
762 void
763 GMT_destroy (struct MeshTunnel3 *t)
764 {
765   struct MeshTConnection *iter;
766   struct MeshTConnection *next;
767
768   if (NULL == t)
769     return;
770
771   LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n", GMP_2s (t->peer));
772
773 //   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &t->id, t))
774 //     GNUNET_break (0);
775
776   for (iter = t->connection_head; NULL != iter; iter = next)
777   {
778     next = iter->next;
779     GMC_destroy (iter->c);
780     GNUNET_free (iter);
781   }
782
783   GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
784   GMP_set_tunnel (t->peer, NULL);
785
786   GNUNET_free (t);
787 }
788
789
790 /**
791  * Notifies a tunnel that a connection has broken that affects at least
792  * some of its peers. Sends a notification towards the root of the tree.
793  * In case the peer is the owner of the tree, notifies the client that owns
794  * the tunnel and tries to reconnect.
795  *
796  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
797  *
798  * @param t Tunnel affected.
799  * @param p1 Peer that got disconnected from p2.
800  * @param p2 Peer that got disconnected from p1.
801  *
802  * @return Short ID of the peer disconnected (either p1 or p2).
803  *         0 if the tunnel remained unaffected.
804  */
805 GNUNET_PEER_Id
806 GMT_notify_connection_broken (struct MeshTunnel3* t,
807                               GNUNET_PEER_Id p1, GNUNET_PEER_Id p2)
808 {
809 //   if (myid != p1 && myid != p2) FIXME
810 //   {
811 //     return;
812 //   }
813 //
814 //   if (tree_get_predecessor (t->tree) != 0)
815 //   {
816 //     /* We are the peer still connected, notify owner of the disconnection. */
817 //     struct GNUNET_MESH_PathBroken msg;
818 //     struct GNUNET_PeerIdentity neighbor;
819 //
820 //     msg.header.size = htons (sizeof (msg));
821 //     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
822 //     GNUNET_PEER_resolve (t->id.oid, &msg.oid);
823 //     msg.tid = htonl (t->id.tid);
824 //     msg.peer1 = my_full_id;
825 //     GNUNET_PEER_resolve (pid, &msg.peer2);
826 //     GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
827 //     send_prebuilt_message (&msg.header, &neighbor, t);
828 //   }
829   return 0;
830 }
831
832 /**
833  * @brief Use the given path for the tunnel.
834  * Update the next and prev hops (and RCs).
835  * (Re)start the path refresh in case the tunnel is locally owned.
836  *
837  * @param t Tunnel to update.
838  * @param p Path to use.
839  *
840  * @return Connection created.
841  */
842 struct MeshConnection *
843 GMT_use_path (struct MeshTunnel3 *t, struct MeshPeerPath *p)
844 {
845   struct MeshConnection *c;
846   struct GNUNET_HashCode cid;
847   unsigned int own_pos;
848
849   if (NULL == t || NULL == p)
850   {
851     GNUNET_break (0);
852     return NULL;
853   }
854
855   for (own_pos = 0; own_pos < p->length; own_pos++)
856   {
857     if (p->peers[own_pos] == my_short_id)
858       break;
859   }
860   if (own_pos > p->length - 1)
861   {
862     GNUNET_break (0);
863     return NULL;
864   }
865
866   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, &cid);
867   c = GMC_new (&cid, t, p, own_pos);
868   GMT_add_connection (t, c);
869   return c;
870 }
871
872
873 /**
874  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
875  * Encrypt data with the tunnel key.
876  *
877  * @param t Tunnel whose key to use.
878  * @param dst Destination for the encrypted data.
879  * @param src Source of the plaintext.
880  * @param size Size of the plaintext.
881  * @param iv Initialization Vector to use.
882  * @param fwd Is this a fwd message?
883  */
884 void
885 GMT_encrypt (struct MeshTunnel3 *t,
886              void *dst, const void *src,
887              size_t size, uint64_t iv, int fwd)
888 {
889   memcpy (dst, src, size);
890 }
891
892
893 /**
894  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
895  * Decrypt data with the tunnel key.
896  *
897  * @param t Tunnel whose key to use.
898  * @param dst Destination for the plaintext.
899  * @param src Source of the encrypted data.
900  * @param size Size of the encrypted data.
901  * @param iv Initialization Vector to use.
902  * @param fwd Is this a fwd message?
903  */
904 void
905 GMT_decrypt (struct MeshTunnel3 *t,
906              void *dst, const void *src,
907              size_t size, uint64_t iv, int fwd)
908 {
909   memcpy (dst, src, size);
910 }
911
912
913 /**
914  * Count established (ready) connections of a tunnel.
915  *
916  * @param t Tunnel on which to count.
917  *
918  * @return Number of connections.
919  */
920 unsigned int
921 GMT_count_connections (struct MeshTunnel3 *t)
922 {
923   struct MeshTConnection *iter;
924   unsigned int count;
925
926   for (count = 0, iter = t->connection_head;
927        NULL != iter;
928        iter = iter->next, count++);
929
930   return count;
931 }
932
933 /**
934  * Count channels of a tunnel.
935  *
936  * @param t Tunnel on which to count.
937  *
938  * @return Number of channels.
939  */
940 unsigned int
941 GMT_count_channels (struct MeshTunnel3 *t)
942 {
943   struct MeshTChannel *iter;
944   unsigned int count;
945
946   for (count = 0, iter = t->channel_head;
947        NULL != iter;
948   iter = iter->next, count++);
949
950   return count;
951 }
952
953
954 /**
955  * Get the total buffer space for a tunnel.
956  *
957  * @param t Tunnel.
958  * @param fwd Is this for FWD traffic?
959  *
960  * @return Buffer space offered by all connections in the tunnel.
961  */
962 unsigned int
963 GMT_get_buffer (struct MeshTunnel3 *t, int fwd)
964 {
965   struct MeshTConnection *iter;
966   unsigned int buffer;
967
968   iter = t->connection_head;
969   buffer = 0;
970
971   /* If terminal, return biggest channel buffer */
972   if (NULL == iter || GMC_is_terminal (iter->c, fwd))
973   {
974     struct MeshTChannel *iter_ch;
975     unsigned int ch_buf;
976
977     if (NULL == t->channel_head)
978       return 64;
979
980     for (iter_ch = t->channel_head; NULL != iter_ch; iter_ch = iter_ch->next)
981     {
982       ch_buf = GMCH_get_buffer (iter_ch->ch, fwd);
983       if (ch_buf > buffer)
984         buffer = ch_buf;
985     }
986     return buffer;
987   }
988
989   /* If not terminal, return sum of connection buffers */
990   while (NULL != iter)
991   {
992     if (GMC_get_state (iter->c) != MESH_CONNECTION_READY)
993     {
994       iter = iter->next;
995       continue;
996     }
997
998     buffer += GMC_get_buffer (iter->c, fwd);
999     iter = iter->next;
1000   }
1001
1002   return buffer;
1003 }
1004
1005 /**
1006  * Sends an already built message on a tunnel, choosing the best connection.
1007  *
1008  * @param message Message to send. Function modifies it.
1009  * @param t Tunnel on which this message is transmitted.
1010  * @param ch Channel on which this message is transmitted.
1011  * @param fwd Is this a fwd message?
1012  */
1013 void
1014 GMT_send_prebuilt_message (struct GNUNET_MESH_Encrypted *msg,
1015                            struct MeshTunnel3 *t,
1016                            struct MeshChannel *ch,
1017                            int fwd)
1018 {
1019   struct MeshConnection *c;
1020   uint16_t type;
1021
1022   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n", GMP_2s (t->peer));
1023   c = tunnel_get_connection (t, fwd);
1024   if (NULL == c)
1025   {
1026     GNUNET_break (GNUNET_YES == t->destroy);
1027     return;
1028   }
1029   type = ntohs (msg->header.type);
1030   switch (type)
1031   {
1032     case GNUNET_MESSAGE_TYPE_MESH_FWD:
1033     case GNUNET_MESSAGE_TYPE_MESH_BCK:
1034     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
1035     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
1036       msg->cid = *GMC_get_id (c);
1037       msg->ttl = htonl (default_ttl);
1038       break;
1039     default:
1040       LOG (GNUNET_ERROR_TYPE_DEBUG, "unkown type %s\n",
1041            GNUNET_MESH_DEBUG_M2S (type));
1042       GNUNET_break (0);
1043   }
1044   msg->reserved = 0;
1045
1046   GMC_send_prebuilt_message (&msg->header, c, ch, fwd);
1047 }