- use per-module logging
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh_connection.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_connection.c
23  * @brief GNUnet MESH service connection handling
24  * @author Bartlomiej Polot
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29
30 #include "gnunet-service-mesh_connection.h"
31 #include "gnunet-service-mesh_peer.h"
32 #include "mesh_protocol_enc.h"
33 #include "mesh_path.h"
34
35
36 #define MESH_MAX_POLL_TIME      GNUNET_TIME_relative_multiply (\
37                                   GNUNET_TIME_UNIT_MINUTES,\
38                                   10)
39 #define MESH_RETRANSMIT_TIME    GNUNET_TIME_UNIT_SECONDS
40 #define MESH_RETRANSMIT_MARGIN  4
41
42 #define LOG (level, ...) GNUNET_log_from ("mesh-con", level, __VA_ARGS__)
43
44 /**
45  * All the states a connection can be in.
46  */
47 enum MeshConnectionState
48 {
49   /**
50    * Uninitialized status, should never appear in operation.
51    */
52   MESH_CONNECTION_NEW,
53
54   /**
55    * Connection create message sent, waiting for ACK.
56    */
57   MESH_CONNECTION_SENT,
58
59   /**
60    * Connection ACK sent, waiting for ACK.
61    */
62   MESH_CONNECTION_ACK,
63
64   /**
65    * Connection confirmed, ready to carry traffic.
66    */
67   MESH_CONNECTION_READY,
68 };
69
70
71
72 /**
73  * Struct containing info about a queued transmission to this peer
74  */
75 struct MeshPeerQueue
76 {
77     /**
78       * DLL next
79       */
80   struct MeshPeerQueue *next;
81
82     /**
83       * DLL previous
84       */
85   struct MeshPeerQueue *prev;
86
87     /**
88      * Peer this transmission is directed to.
89      */
90   struct MeshPeer *peer;
91
92     /**
93      * Connection this message belongs to.
94      */
95   struct MeshConnection *c;
96
97     /**
98      * Is FWD in c?
99      */
100   int fwd;
101
102     /**
103      * Channel this message belongs to, if known.
104      */
105   struct MeshChannel *ch;
106
107     /**
108      * Pointer to info stucture used as cls.
109      */
110   void *cls;
111
112     /**
113      * Type of message
114      */
115   uint16_t type;
116
117     /**
118      * Size of the message
119      */
120   size_t size;
121 };
122
123
124 /**
125  * Struct to encapsulate all the Flow Control information to a peer to which
126  * we are directly connected (on a core level).
127  */
128 struct MeshFlowControl
129 {
130   /**
131    * Connection this controls.
132    */
133   struct MeshConnection *c;
134
135   /**
136    * How many messages are in the queue on this connection.
137    */
138   unsigned int queue_n;
139
140   /**
141    * How many messages do we accept in the queue.
142    */
143   unsigned int queue_max;
144
145   /**
146    * Next ID to use.
147    */
148   uint32_t next_pid;
149
150   /**
151    * ID of the last packet sent towards the peer.
152    */
153   uint32_t last_pid_sent;
154
155   /**
156    * ID of the last packet received from the peer.
157    */
158   uint32_t last_pid_recv;
159
160   /**
161    * Last ACK sent to the peer (peer can't send more than this PID).
162    */
163   uint32_t last_ack_sent;
164
165   /**
166    * Last ACK sent towards the origin (for traffic towards leaf node).
167    */
168   uint32_t last_ack_recv;
169
170   /**
171    * Task to poll the peer in case of a lost ACK causes stall.
172    */
173   GNUNET_SCHEDULER_TaskIdentifier poll_task;
174
175   /**
176    * How frequently to poll for ACKs.
177    */
178   struct GNUNET_TIME_Relative poll_time;
179 };
180
181
182 /**
183  * Struct containing all information regarding a connection to a peer.
184  */
185 struct MeshConnection
186 {
187   /**
188    * DLL
189    */
190   struct MeshConnection *next;
191   struct MeshConnection *prev;
192
193   /**
194    * Tunnel this connection is part of.
195    */
196   struct MeshTunnel2 *t;
197
198   /**
199    * Flow control information for traffic fwd.
200    */
201   struct MeshFlowControl fwd_fc;
202
203   /**
204    * Flow control information for traffic bck.
205    */
206   struct MeshFlowControl bck_fc;
207
208   /**
209    * ID of the connection.
210    */
211   struct GNUNET_HashCode id;
212
213   /**
214    * State of the connection.
215    */
216   enum MeshConnectionState state;
217
218   /**
219    * Path being used for the tunnel.
220    */
221   struct MeshPeerPath *path;
222
223   /**
224    * Position of the local peer in the path.
225    */
226   unsigned int own_pos;
227
228   /**
229    * Task to keep the used paths alive at the owner,
230    * time tunnel out on all the other peers.
231    */
232   GNUNET_SCHEDULER_TaskIdentifier fwd_maintenance_task;
233
234   /**
235    * Task to keep the used paths alive at the destination,
236    * time tunnel out on all the other peers.
237    */
238   GNUNET_SCHEDULER_TaskIdentifier bck_maintenance_task;
239
240   /**
241    * Pending message count.
242    */
243   int pending_messages;
244
245   /**
246    * Destroy flag: if true, destroy on last message.
247    */
248   int destroy;
249 };
250
251
252 /**
253  * Connections known, indexed by cid (MeshConnection).
254  */
255 static struct GNUNET_CONTAINER_MultiHashMap *connections;
256
257 /**
258  * How many connections are we willing to maintain.
259  * Local connections are always allowed, even if there are more connections than max.
260  */
261 static unsigned long long max_connections;
262
263 /**
264  * How many messages *in total* are we willing to queue, divide by number of
265  * connections to get connection queue size.
266  */
267 static unsigned long long max_msgs_queue;
268
269 /**
270  * How often to send path keepalives. Paths timeout after 4 missed.
271  */
272 static struct GNUNET_TIME_Relative refresh_connection_time;
273
274
275 #if 0 // avoid compiler warning for unused static function
276 static void
277 fc_debug (struct MeshFlowControl *fc)
278 {
279   LOG (GNUNET_ERROR_TYPE_DEBUG, "    IN: %u/%u\n",
280               fc->last_pid_recv, fc->last_ack_sent);
281   LOG (GNUNET_ERROR_TYPE_DEBUG, "    OUT: %u/%u\n",
282               fc->last_pid_sent, fc->last_ack_recv);
283   LOG (GNUNET_ERROR_TYPE_DEBUG, "    QUEUE: %u/%u\n",
284               fc->queue_n, fc->queue_max);
285 }
286
287 static void
288 connection_debug (struct MeshConnection *c)
289 {
290   if (NULL == c)
291   {
292     LOG (GNUNET_ERROR_TYPE_DEBUG, "*** DEBUG NULL CONNECTION ***\n");
293     return;
294   }
295   LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection %s:%X\n",
296               peer2s (c->t->peer), GNUNET_h2s (&c->id));
297   LOG (GNUNET_ERROR_TYPE_DEBUG, "  state: %u, pending msgs: %u\n",
298               c->state, c->pending_messages);
299   LOG (GNUNET_ERROR_TYPE_DEBUG, "  FWD FC\n");
300   fc_debug (&c->fwd_fc);
301   LOG (GNUNET_ERROR_TYPE_DEBUG, "  BCK FC\n");
302   fc_debug (&c->bck_fc);
303 }
304 #endif
305
306 /**
307  * Get string description for tunnel state.
308  *
309  * @param s Tunnel state.
310  *
311  * @return String representation.
312  */
313 static const char *
314 GMC_DEBUG_state2s (enum MeshTunnelState s)
315 {
316   switch (s)
317   {
318     case MESH_CONNECTION_NEW:
319       return "MESH_CONNECTION_NEW";
320     case MESH_CONNECTION_SENT:
321       return "MESH_CONNECTION_SENT";
322     case MESH_CONNECTION_ACK:
323       return "MESH_CONNECTION_ACK";
324     case MESH_CONNECTION_READY:
325       return "MESH_CONNECTION_READY";
326     default:
327       return "MESH_CONNECTION_STATE_ERROR";
328   }
329 }
330
331
332
333 /**
334  * Initialize a Flow Control structure to the initial state.
335  *
336  * @param fc Flow Control structure to initialize.
337  */
338 static void
339 fc_init (struct MeshFlowControl *fc)
340 {
341   fc->next_pid = 0;
342   fc->last_pid_sent = (uint32_t) -1; /* Next (expected) = 0 */
343   fc->last_pid_recv = (uint32_t) -1;
344   fc->last_ack_sent = (uint32_t) 0;
345   fc->last_ack_recv = (uint32_t) 0;
346   fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
347   fc->poll_time = GNUNET_TIME_UNIT_SECONDS;
348   fc->queue_n = 0;
349   fc->queue_max = (max_msgs_queue / max_connections) + 1;
350 }
351
352
353 /**
354  * Find a connection.
355  *
356  * @param cid Connection ID.
357  */
358 static struct MeshConnection *
359 connection_get (const struct GNUNET_HashCode *cid)
360 {
361   return GNUNET_CONTAINER_multihashmap_get (connections, cid);
362 }
363
364
365 /**
366  * Send an ACK informing the predecessor about the available buffer space.
367  *
368  * Note that for fwd ack, the FWD mean forward *traffic* (root->dest),
369  * the ACK itself goes "back" (dest->root).
370  *
371  * @param c Connection on which to send the ACK.
372  * @param buffer How much space free to advertise?
373  * @param fwd Is this FWD ACK? (Going dest->owner)
374  */
375 static void
376 connection_send_ack (struct MeshConnection *c, unsigned int buffer, int fwd)
377 {
378   struct MeshFlowControl *next_fc;
379   struct MeshFlowControl *prev_fc;
380   struct GNUNET_MESH_ACK msg;
381   uint32_t ack;
382   int delta;
383
384   next_fc = fwd ? &c->fwd_fc : &c->bck_fc;
385   prev_fc = fwd ? &c->bck_fc : &c->fwd_fc;
386
387   LOG (GNUNET_ERROR_TYPE_DEBUG,
388               "connection send %s ack on %s\n",
389               fwd ? "FWD" : "BCK", GNUNET_h2s (&c->id));
390
391   /* Check if we need to transmit the ACK */
392   if (prev_fc->last_ack_sent - prev_fc->last_pid_recv > 3)
393   {
394     LOG (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, buffer > 3\n");
395     LOG (GNUNET_ERROR_TYPE_DEBUG,
396                 "  last pid recv: %u, last ack sent: %u\n",
397                 prev_fc->last_pid_recv, prev_fc->last_ack_sent);
398     return;
399   }
400
401   /* Ok, ACK might be necessary, what PID to ACK? */
402   delta = next_fc->queue_max - next_fc->queue_n;
403   ack = prev_fc->last_pid_recv + delta;
404   LOG (GNUNET_ERROR_TYPE_DEBUG, " ACK %u\n", ack);
405   LOG (GNUNET_ERROR_TYPE_DEBUG,
406               " last pid %u, last ack %u, qmax %u, q %u\n",
407               prev_fc->last_pid_recv, prev_fc->last_ack_sent,
408               next_fc->queue_max, next_fc->queue_n);
409   if (ack == prev_fc->last_ack_sent)
410   {
411     LOG (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, not needed\n");
412     return;
413   }
414
415   prev_fc->last_ack_sent = ack;
416
417   /* Build ACK message and send on connection */
418   msg.header.size = htons (sizeof (msg));
419   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ACK);
420   msg.ack = htonl (ack);
421   msg.cid = c->id;
422
423   send_prebuilt_message_connection (&msg.header, c, NULL, !fwd);
424 }
425
426
427 /**
428  * Sends a CONNECTION ACK message in reponse to a received CONNECTION_CREATE
429  * directed to us.
430  *
431  * @param connection Connection to confirm.
432  * @param fwd Is this a fwd ACK? (First is bck (SYNACK), second is fwd (ACK))
433  */
434 static void
435 send_connection_ack (struct MeshConnection *connection, int fwd)
436 {
437   struct MeshTunnel2 *t;
438
439   t = connection->t;
440   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send connection ack\n");
441   queue_add (NULL,
442              GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK,
443              sizeof (struct GNUNET_MESH_ConnectionACK),
444              connection,
445              NULL,
446              fwd);
447   if (MESH_TUNNEL_NEW == t->state)
448     tunnel_change_state (t, MESH_TUNNEL_WAITING);
449   if (MESH_CONNECTION_READY != connection->state)
450     connection_change_state (connection, MESH_CONNECTION_SENT);
451 }
452
453
454 /**
455  * Sends a CREATE CONNECTION message for a path to a peer.
456  * Changes the connection and tunnel states if necessary.
457  *
458  * @param connection Connection to create.
459  */
460 static void
461 send_connection_create (struct MeshConnection *connection)
462 {
463   struct MeshTunnel2 *t;
464
465   t = connection->t;
466   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send connection create\n");
467   queue_add (NULL,
468              GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE,
469              sizeof (struct GNUNET_MESH_ConnectionCreate) +
470                 (connection->path->length *
471                  sizeof (struct GNUNET_PeerIdentity)),
472              connection,
473              NULL,
474              GNUNET_YES);
475   if (NULL != t &&
476       (MESH_TUNNEL_SEARCHING == t->state || MESH_TUNNEL_NEW == t->state))
477     tunnel_change_state (t, MESH_TUNNEL_WAITING);
478   if (MESH_CONNECTION_NEW == connection->state)
479     connection_change_state (connection, MESH_CONNECTION_SENT);
480 }
481
482
483 static void
484 connection_change_state (struct MeshConnection* c,
485                          enum MeshConnectionState state)
486 {
487   LOG (GNUNET_ERROR_TYPE_DEBUG,
488               "Connection %s state was %s\n",
489               GNUNET_h2s (&c->id), GNUNET_MESH_DEBUG_CS2S (c->state));
490   LOG (GNUNET_ERROR_TYPE_DEBUG,
491               "Connection %s state is now %s\n",
492               GNUNET_h2s (&c->id), GNUNET_MESH_DEBUG_CS2S (state));
493   c->state = state;
494 }
495
496
497
498 /**
499  * Send keepalive packets for a connection.
500  *
501  * @param c Connection to keep alive..
502  * @param fwd Is this a FWD keepalive? (owner -> dest).
503  */
504 static void
505 connection_keepalive (struct MeshConnection *c, int fwd)
506 {
507   struct GNUNET_MESH_ConnectionKeepAlive *msg;
508   size_t size = sizeof (struct GNUNET_MESH_ConnectionKeepAlive);
509   char cbuf[size];
510   uint16_t type;
511
512   type = fwd ? GNUNET_MESSAGE_TYPE_MESH_FWD_KEEPALIVE :
513                GNUNET_MESSAGE_TYPE_MESH_BCK_KEEPALIVE;
514
515   LOG (GNUNET_ERROR_TYPE_DEBUG,
516               "sending %s keepalive for connection %s[%d]\n",
517               fwd ? "FWD" : "BCK",
518               peer2s (c->t->peer),
519               c->id);
520
521   msg = (struct GNUNET_MESH_ConnectionKeepAlive *) cbuf;
522   msg->header.size = htons (size);
523   msg->header.type = htons (type);
524   msg->cid = c->id;
525
526   send_prebuilt_message_connection (&msg->header, c, NULL, fwd);
527 }
528
529
530 /**
531  * Send CONNECTION_{CREATE/ACK} packets for a connection.
532  *
533  * @param c Connection for which to send the message.
534  * @param fwd If GNUNET_YES, send CREATE, otherwise send ACK.
535  */
536 static void
537 connection_recreate (struct MeshConnection *c, int fwd)
538 {
539   LOG (GNUNET_ERROR_TYPE_DEBUG, "sending connection recreate\n");
540   if (fwd)
541     send_connection_create (c);
542   else
543     send_connection_ack (c, GNUNET_NO);
544 }
545
546
547 /**
548  * Generic connection timer management.
549  * Depending on the role of the peer in the connection will send the
550  * appropriate message (build or keepalive)
551  *
552  * @param c Conncetion to maintain.
553  * @param fwd Is FWD?
554  */
555 static void
556 connection_maintain (struct MeshConnection *c, int fwd)
557 {
558   if (MESH_TUNNEL_SEARCHING == c->t->state)
559   {
560     /* TODO DHT GET with RO_BART */
561     return;
562   }
563   switch (c->state)
564   {
565     case MESH_CONNECTION_NEW:
566       GNUNET_break (0);
567     case MESH_CONNECTION_SENT:
568       connection_recreate (c, fwd);
569       break;
570     case MESH_CONNECTION_READY:
571       connection_keepalive (c, fwd);
572       break;
573     default:
574       break;
575   }
576 }
577
578
579 static void
580 connection_fwd_keepalive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
581 {
582   struct MeshConnection *c = cls;
583
584   c->fwd_maintenance_task = GNUNET_SCHEDULER_NO_TASK;
585   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
586     return;
587
588   connection_maintain (c, GNUNET_YES);
589   c->fwd_maintenance_task = GNUNET_SCHEDULER_add_delayed (refresh_connection_time,
590                                                           &connection_fwd_keepalive,
591                                                           c);
592 }
593
594
595 static void
596 connection_bck_keepalive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
597 {
598   struct MeshConnection *c = cls;
599
600   c->bck_maintenance_task = GNUNET_SCHEDULER_NO_TASK;
601   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
602     return;
603
604   connection_maintain (c, GNUNET_NO);
605   c->bck_maintenance_task = GNUNET_SCHEDULER_add_delayed (refresh_connection_time,
606                                                           &connection_bck_keepalive,
607                                                           c);
608 }
609
610
611 /**
612  * Send a message to all peers in this connection that the connection
613  * is no longer valid.
614  *
615  * If some peer should not receive the message, it should be zero'ed out
616  * before calling this function.
617  *
618  * @param c The connection whose peers to notify.
619  */
620 static void
621 connection_send_destroy (struct MeshConnection *c)
622 {
623   struct GNUNET_MESH_ConnectionDestroy msg;
624
625   msg.header.size = htons (sizeof (msg));
626   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY);;
627   msg.cid = c->id;
628   LOG (GNUNET_ERROR_TYPE_DEBUG,
629               "  sending connection destroy for connection %s[%X]\n",
630               peer2s (c->t->peer),
631               c->id);
632
633   if (GNUNET_NO == GMC_is_terminal (c, GNUNET_YES))
634     send_prebuilt_message_connection (&msg.header, c, NULL, GNUNET_YES);
635   if (GNUNET_NO == GMC_is_terminal (c, GNUNET_NO))
636     send_prebuilt_message_connection (&msg.header, c, NULL, GNUNET_NO);
637   c->destroy = GNUNET_YES;
638 }
639
640
641 /**
642  * Get free buffer space in a connection.
643  *
644  * @param c Connection.
645  * @param fwd Is query about FWD traffic?
646  *
647  * @return Free buffer space [0 - max_msgs_queue/max_connections]
648  */
649 static unsigned int
650 connection_get_buffer (struct MeshConnection *c, int fwd)
651 {
652   struct MeshFlowControl *fc;
653
654   fc = fwd ? &c->fwd_fc : &c->bck_fc;
655
656   return (fc->queue_max - fc->queue_n);
657 }
658
659
660 /**
661  * Get the first transmittable message for a connection.
662  *
663  * @param c Connection.
664  * @param fwd Is this FWD?
665  *
666  * @return First transmittable message.
667  */
668 static struct MeshPeerQueue *
669 connection_get_first_message (struct MeshConnection *c, int fwd)
670 {
671   struct MeshPeerQueue *q;
672   struct MeshPeer *p;
673
674   p = connection_get_hop (c, fwd);
675
676   for (q = p->queue_head; NULL != q; q = q->next)
677   {
678     if (q->c != c)
679       continue;
680     if (queue_is_sendable (q))
681       return q;
682   }
683
684   return NULL;
685 }
686
687
688 /**
689  * @brief Re-initiate traffic on this connection if necessary.
690  *
691  * Check if there is traffic queued towards this peer
692  * and the core transmit handle is NULL (traffic was stalled).
693  * If so, call core tmt rdy.
694  *
695  * @param c Connection on which initiate traffic.
696  * @param fwd Is this about fwd traffic?
697  */
698 static void
699 connection_unlock_queue (struct MeshConnection *c, int fwd)
700 {
701   struct MeshPeer *peer;
702   struct MeshPeerQueue *q;
703   size_t size;
704
705   LOG (GNUNET_ERROR_TYPE_DEBUG,
706               "connection_unlock_queue %s on %s\n",
707               fwd ? "FWD" : "BCK", GNUNET_h2s (&c->id));
708
709   if (GMC_is_terminal (c, fwd))
710   {
711     LOG (GNUNET_ERROR_TYPE_DEBUG, " is terminal!\n");
712     return;
713   }
714
715   peer = connection_get_hop (c, fwd);
716
717   if (NULL != peer->core_transmit)
718   {
719     LOG (GNUNET_ERROR_TYPE_DEBUG, "  already unlocked!\n");
720     return; /* Already unlocked */
721   }
722
723   q = connection_get_first_message (c, fwd);
724   if (NULL == q)
725   {
726     LOG (GNUNET_ERROR_TYPE_DEBUG, "  queue empty!\n");
727     return; /* Nothing to transmit */
728   }
729
730   size = q->size;
731   peer->core_transmit =
732       GNUNET_CORE_notify_transmit_ready (core_handle,
733                                          GNUNET_NO,
734                                          0,
735                                          GNUNET_TIME_UNIT_FOREVER_REL,
736                                          GNUNET_PEER_resolve2 (peer->id),
737                                          size,
738                                          &queue_send,
739                                          peer);
740 }
741
742
743 /**
744  * Cancel all transmissions that belong to a certain connection.
745  *
746  * @param c Connection which to cancel.
747  * @param fwd Cancel fwd traffic?
748  */
749 static void
750 connection_cancel_queues (struct MeshConnection *c, int fwd)
751 {
752   struct MeshPeerQueue *q;
753   struct MeshPeerQueue *next;
754   struct MeshFlowControl *fc;
755   struct MeshPeer *peer;
756
757   if (NULL == c)
758   {
759     GNUNET_break (0);
760     return;
761   }
762   fc = fwd ? &c->fwd_fc : &c->bck_fc;
763   peer = connection_get_hop (c, fwd);
764
765   for (q = peer->queue_head; NULL != q; q = next)
766   {
767     next = q->next;
768     if (q->c == c)
769     {
770       LOG (GNUNET_ERROR_TYPE_DEBUG,
771                   "connection_cancel_queue %s\n",
772                   GNUNET_MESH_DEBUG_M2S (q->type));
773       queue_destroy (q, GNUNET_YES);
774     }
775   }
776   if (NULL == peer->queue_head)
777   {
778     if (NULL != peer->core_transmit)
779     {
780       GNUNET_CORE_notify_transmit_ready_cancel (peer->core_transmit);
781       peer->core_transmit = NULL;
782     }
783     if (GNUNET_SCHEDULER_NO_TASK != fc->poll_task)
784     {
785       GNUNET_SCHEDULER_cancel (fc->poll_task);
786       fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
787     }
788   }
789 }
790
791
792
793
794 /**
795  * Function called if a connection has been stalled for a while,
796  * possibly due to a missed ACK. Poll the neighbor about its ACK status.
797  *
798  * @param cls Closure (poll ctx).
799  * @param tc TaskContext.
800  */
801 static void
802 connection_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
803 {
804   struct MeshFlowControl *fc = cls;
805   struct GNUNET_MESH_Poll msg;
806   struct MeshConnection *c;
807
808   fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
809   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
810   {
811     return;
812   }
813
814   c = fc->c;
815   LOG (GNUNET_ERROR_TYPE_DEBUG, " *** Polling!\n");
816   LOG (GNUNET_ERROR_TYPE_DEBUG, " *** connection [%X]\n",
817               GNUNET_h2s (&c->id));
818   LOG (GNUNET_ERROR_TYPE_DEBUG, " ***   %s\n",
819               fc == &c->fwd_fc ? "FWD" : "BCK");
820
821   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL);
822   msg.header.size = htons (sizeof (msg));
823   LOG (GNUNET_ERROR_TYPE_DEBUG, " *** pid (%u)!\n", fc->last_pid_sent);
824   send_prebuilt_message_connection (&msg.header, c, NULL, fc == &c->fwd_fc);
825   fc->poll_time = GNUNET_TIME_STD_BACKOFF (fc->poll_time);
826   fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
827                                                 &connection_poll, fc);
828 }
829
830
831
832
833 /**
834  * Get the previous hop in a connection
835  *
836  * @param c Connection.
837  *
838  * @return Previous peer in the connection.
839  */
840 static struct MeshPeer *
841 connection_get_prev_hop (struct MeshConnection *c)
842 {
843   GNUNET_PEER_Id id;
844
845   if (0 == c->own_pos || c->path->length < 2)
846     id = c->path->peers[0];
847   else
848     id = c->path->peers[c->own_pos - 1];
849
850   return peer_get_short (id);
851 }
852
853
854 /**
855  * Get the next hop in a connection
856  *
857  * @param c Connection.
858  *
859  * @return Next peer in the connection.
860  */
861 static struct MeshPeer *
862 connection_get_next_hop (struct MeshConnection *c)
863 {
864   GNUNET_PEER_Id id;
865
866   if ((c->path->length - 1) == c->own_pos || c->path->length < 2)
867     id = c->path->peers[c->path->length - 1];
868   else
869     id = c->path->peers[c->own_pos + 1];
870
871   return peer_get_short (id);
872 }
873
874
875 /**
876  * Get the hop in a connection.
877  *
878  * @param c Connection.
879  * @param fwd Next hop?
880  *
881  * @return Next peer in the connection.
882  */
883 static struct MeshPeer *
884 connection_get_hop (struct MeshConnection *c, int fwd)
885 {
886   if (fwd)
887     return connection_get_next_hop (c);
888   return connection_get_prev_hop (c);
889 }
890
891
892
893
894 /**
895  * Timeout function due to lack of keepalive/traffic from the owner.
896  * Destroys connection if called.
897  *
898  * @param cls Closure (connection to destroy).
899  * @param tc TaskContext.
900  */
901 static void
902 connection_fwd_timeout (void *cls,
903                         const struct GNUNET_SCHEDULER_TaskContext *tc)
904 {
905   struct MeshConnection *c = cls;
906
907   c->fwd_maintenance_task = GNUNET_SCHEDULER_NO_TASK;
908   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
909     return;
910   LOG (GNUNET_ERROR_TYPE_DEBUG,
911               "Connection %s[%X] FWD timed out. Destroying.\n",
912               peer2s (c->t->peer),
913               c->id);
914
915   if (GMC_is_origin (c, GNUNET_YES)) /* If local, leave. */
916     return;
917
918   GMC_destroy (c);
919 }
920
921
922 /**
923  * Timeout function due to lack of keepalive/traffic from the destination.
924  * Destroys connection if called.
925  *
926  * @param cls Closure (connection to destroy).
927  * @param tc TaskContext
928  */
929 static void
930 connection_bck_timeout (void *cls,
931                         const struct GNUNET_SCHEDULER_TaskContext *tc)
932 {
933   struct MeshConnection *c = cls;
934
935   c->bck_maintenance_task = GNUNET_SCHEDULER_NO_TASK;
936   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
937     return;
938
939   LOG (GNUNET_ERROR_TYPE_DEBUG,
940               "Connection %s[%X] FWD timed out. Destroying.\n",
941               peer2s (c->t->peer),
942               c->id);
943
944   if (GMC_is_origin (c, GNUNET_NO)) /* If local, leave. */
945     return;
946
947   GMC_destroy (c);
948 }
949
950
951 /**
952  * Resets the connection timeout task, some other message has done the
953  * task's job.
954  * - For the first peer on the direction this means to send
955  *   a keepalive or a path confirmation message (either create or ACK).
956  * - For all other peers, this means to destroy the connection,
957  *   due to lack of activity.
958  * Starts the tiemout if no timeout was running (connection just created).
959  *
960  * @param c Connection whose timeout to reset.
961  * @param fwd Is this forward?
962  *
963  * TODO use heap to improve efficiency of scheduler.
964  */
965 static void
966 connection_reset_timeout (struct MeshConnection *c, int fwd)
967 {
968   GNUNET_SCHEDULER_TaskIdentifier *ti;
969   GNUNET_SCHEDULER_Task f;
970
971   ti = fwd ? &c->fwd_maintenance_task : &c->bck_maintenance_task;
972
973   if (GNUNET_SCHEDULER_NO_TASK != *ti)
974     GNUNET_SCHEDULER_cancel (*ti);
975
976   if (GMC_is_origin (c, fwd)) /* Endpoint */
977   {
978     f  = fwd ? &connection_fwd_keepalive : &connection_bck_keepalive;
979     *ti = GNUNET_SCHEDULER_add_delayed (refresh_connection_time, f, c);
980   }
981   else /* Relay */
982   {
983     struct GNUNET_TIME_Relative delay;
984
985     delay = GNUNET_TIME_relative_multiply (refresh_connection_time, 4);
986     f  = fwd ? &connection_fwd_timeout : &connection_bck_timeout;
987     *ti = GNUNET_SCHEDULER_add_delayed (delay, f, c);
988   }
989 }
990
991
992 /**
993  * Core handler for connection creation.
994  *
995  * @param cls Closure (unused).
996  * @param peer Sender (neighbor).
997  * @param message Message.
998  *
999  * @return GNUNET_OK to keep the connection open,
1000  *         GNUNET_SYSERR to close it (signal serious error)
1001  */
1002 int
1003 GMC_handle_create (void *cls, const struct GNUNET_PeerIdentity *peer,
1004                    const struct GNUNET_MessageHeader *message)
1005 {
1006   struct GNUNET_MESH_ConnectionCreate *msg;
1007   struct GNUNET_PeerIdentity *id;
1008   struct GNUNET_HashCode *cid;
1009   struct MeshPeerPath *path;
1010   struct MeshPeer *dest_peer;
1011   struct MeshPeer *orig_peer;
1012   struct MeshConnection *c;
1013   unsigned int own_pos;
1014   uint16_t size;
1015   uint16_t i;
1016
1017   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
1018   LOG (GNUNET_ERROR_TYPE_DEBUG, "Received a connection create msg\n");
1019
1020   /* Check size */
1021   size = ntohs (message->size);
1022   if (size < sizeof (struct GNUNET_MESH_ConnectionCreate))
1023   {
1024     GNUNET_break_op (0);
1025     return GNUNET_OK;
1026   }
1027
1028   /* Calculate hops */
1029   size -= sizeof (struct GNUNET_MESH_ConnectionCreate);
1030   if (size % sizeof (struct GNUNET_PeerIdentity))
1031   {
1032     GNUNET_break_op (0);
1033     return GNUNET_OK;
1034   }
1035   size /= sizeof (struct GNUNET_PeerIdentity);
1036   if (1 > size)
1037   {
1038     GNUNET_break_op (0);
1039     return GNUNET_OK;
1040   }
1041   LOG (GNUNET_ERROR_TYPE_DEBUG, "    path has %u hops.\n", size);
1042
1043   /* Get parameters */
1044   msg = (struct GNUNET_MESH_ConnectionCreate *) message;
1045   cid = &msg->cid;
1046   id = (struct GNUNET_PeerIdentity *) &msg[1];
1047   LOG (GNUNET_ERROR_TYPE_DEBUG,
1048               "    connection %s (%s).\n",
1049               GNUNET_h2s (cid), GNUNET_i2s (id));
1050
1051   /* Create connection */
1052   c = connection_get (cid);
1053   if (NULL == c)
1054   {
1055     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Creating connection\n");
1056     c = connection_new (cid);
1057     if (NULL == c)
1058       return GNUNET_OK;
1059     connection_reset_timeout (c, GNUNET_YES);
1060
1061     /* Create path */
1062     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Creating path...\n");
1063     path = path_new (size);
1064     own_pos = 0;
1065     for (i = 0; i < size; i++)
1066     {
1067       LOG (GNUNET_ERROR_TYPE_DEBUG, "  ... adding %s\n",
1068                   GNUNET_i2s (&id[i]));
1069       path->peers[i] = GNUNET_PEER_intern (&id[i]);
1070       if (path->peers[i] == myid)
1071         own_pos = i;
1072     }
1073     if (own_pos == 0 && path->peers[own_pos] != myid)
1074     {
1075       /* create path: self not found in path through self */
1076       GNUNET_break_op (0);
1077       path_destroy (path);
1078       connection_destroy (c);
1079       return GNUNET_OK;
1080     }
1081     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Own position: %u\n", own_pos);
1082     path_add_to_peers (path, GNUNET_NO);
1083     c->path = path_duplicate (path);
1084     c->own_pos = own_pos;
1085   }
1086   else
1087   {
1088     path = NULL;
1089   }
1090   if (MESH_CONNECTION_NEW == c->state)
1091     connection_change_state (c, MESH_CONNECTION_SENT);
1092
1093   /* Remember peers */
1094   dest_peer = peer_get (&id[size - 1]);
1095   orig_peer = peer_get (&id[0]);
1096
1097   /* Is it a connection to us? */
1098   if (c->own_pos == size - 1)
1099   {
1100     LOG (GNUNET_ERROR_TYPE_DEBUG, "  It's for us!\n");
1101     peer_add_path_to_origin (orig_peer, path, GNUNET_YES);
1102
1103     if (NULL == orig_peer->tunnel)
1104     {
1105       orig_peer->tunnel = tunnel_new ();
1106       orig_peer->tunnel->peer = orig_peer;
1107     }
1108     tunnel_add_connection (orig_peer->tunnel, c);
1109     if (MESH_TUNNEL_NEW == c->t->state)
1110       tunnel_change_state (c->t,  MESH_TUNNEL_WAITING);
1111
1112     send_connection_ack (c, GNUNET_NO);
1113     if (MESH_CONNECTION_SENT == c->state)
1114       connection_change_state (c, MESH_CONNECTION_ACK);
1115
1116     /* Keep tunnel alive in direction dest->owner*/
1117     connection_reset_timeout (c, GNUNET_NO);
1118   }
1119   else
1120   {
1121     /* It's for somebody else! Retransmit. */
1122     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Retransmitting.\n");
1123     peer_add_path (dest_peer, path_duplicate (path), GNUNET_NO);
1124     peer_add_path_to_origin (orig_peer, path, GNUNET_NO);
1125     send_prebuilt_message_connection (message, c, NULL, GNUNET_YES);
1126   }
1127   return GNUNET_OK;
1128 }
1129
1130
1131 /**
1132  * Core handler for path confirmations.
1133  *
1134  * @param cls closure
1135  * @param message message
1136  * @param peer peer identity this notification is about
1137  *
1138  * @return GNUNET_OK to keep the connection open,
1139  *         GNUNET_SYSERR to close it (signal serious error)
1140  */
1141 int
1142 GMC_handle_confirm (void *cls, const struct GNUNET_PeerIdentity *peer,
1143                     const struct GNUNET_MessageHeader *message)
1144 {
1145   struct GNUNET_MESH_ConnectionACK *msg;
1146   struct MeshConnection *c;
1147   struct MeshPeerPath *p;
1148   struct MeshPeer *pi;
1149   int fwd;
1150
1151   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
1152   LOG (GNUNET_ERROR_TYPE_DEBUG, "Received a connection ACK msg\n");
1153   msg = (struct GNUNET_MESH_ConnectionACK *) message;
1154   LOG (GNUNET_ERROR_TYPE_DEBUG, "  on connection %s\n",
1155               GNUNET_h2s (&msg->cid));
1156   c = connection_get (&msg->cid);
1157   if (NULL == c)
1158   {
1159     GNUNET_STATISTICS_update (stats, "# control on unknown connection",
1160                               1, GNUNET_NO);
1161     LOG (GNUNET_ERROR_TYPE_DEBUG, "  don't know the connection!\n");
1162     return GNUNET_OK;
1163   }
1164
1165
1166   LOG (GNUNET_ERROR_TYPE_DEBUG, "  via peer %s\n",
1167               GNUNET_i2s (peer));
1168   pi = peer_get (peer);
1169   if (connection_get_next_hop (c) == pi)
1170   {
1171     LOG (GNUNET_ERROR_TYPE_DEBUG, "  SYNACK\n");
1172     fwd = GNUNET_NO;
1173     if (MESH_CONNECTION_SENT == c->state)
1174       connection_change_state (c, MESH_CONNECTION_ACK);
1175   }
1176   else if (connection_get_prev_hop (c) == pi)
1177   {
1178     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ACK\n");
1179     fwd = GNUNET_YES;
1180     connection_change_state (c, MESH_CONNECTION_READY);
1181   }
1182   else
1183   {
1184     GNUNET_break_op (0);
1185     return GNUNET_OK;
1186   }
1187   connection_reset_timeout (c, fwd);
1188
1189   /* Add path to peers? */
1190   p = c->path;
1191   if (NULL != p)
1192   {
1193     path_add_to_peers (p, GNUNET_YES);
1194   }
1195   else
1196   {
1197     GNUNET_break (0);
1198   }
1199
1200   /* Message for us as creator? */
1201   if (connection_is_origin (c, GNUNET_YES))
1202   {
1203     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Connection (SYN)ACK for us!\n");
1204     connection_change_state (c, MESH_CONNECTION_READY);
1205     if (MESH_TUNNEL_READY != c->t->state)
1206       tunnel_change_state (c->t, MESH_TUNNEL_READY);
1207     send_connection_ack (c, GNUNET_YES);
1208     tunnel_send_queued_data (c->t, GNUNET_YES);
1209     if (3 <= tunnel_count_connections (c->t) && NULL != c->t->peer->dhtget)
1210     {
1211       GNUNET_DHT_get_stop (c->t->peer->dhtget);
1212       c->t->peer->dhtget = NULL;
1213     }
1214     return GNUNET_OK;
1215   }
1216
1217   /* Message for us as destination? */
1218   if (GMC_is_terminal (c, GNUNET_YES))
1219   {
1220     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Connection ACK for us!\n");
1221     if (MESH_TUNNEL_READY != c->t->state)
1222       tunnel_change_state (c->t, MESH_TUNNEL_READY);
1223     connection_change_state (c, MESH_CONNECTION_READY);
1224     tunnel_send_queued_data (c->t, GNUNET_NO);
1225     return GNUNET_OK;
1226   }
1227
1228   LOG (GNUNET_ERROR_TYPE_DEBUG, "  not for us, retransmitting...\n");
1229   send_prebuilt_message_connection (message, c, NULL, fwd);
1230   return GNUNET_OK;
1231 }
1232
1233
1234 /**
1235  * Core handler for notifications of broken paths
1236  *
1237  * @param cls Closure (unused).
1238  * @param peer Peer identity of sending neighbor.
1239  * @param message Message.
1240  *
1241  * @return GNUNET_OK to keep the connection open,
1242  *         GNUNET_SYSERR to close it (signal serious error)
1243  */
1244 int
1245 GMC_handle_broken (void *cls, const struct GNUNET_PeerIdentity *peer,
1246                    const struct GNUNET_MessageHeader *message)
1247 {
1248   struct GNUNET_MESH_ConnectionBroken *msg;
1249   struct MeshConnection *c;
1250
1251   LOG (GNUNET_ERROR_TYPE_DEBUG,
1252               "Received a CONNECTION BROKEN msg from %s\n", GNUNET_i2s (peer));
1253   msg = (struct GNUNET_MESH_ConnectionBroken *) message;
1254   LOG (GNUNET_ERROR_TYPE_DEBUG, "  regarding %s\n",
1255               GNUNET_i2s (&msg->peer1));
1256   LOG (GNUNET_ERROR_TYPE_DEBUG, "  regarding %s\n",
1257               GNUNET_i2s (&msg->peer2));
1258   c = connection_get (&msg->cid);
1259   if (NULL == c)
1260   {
1261     GNUNET_break_op (0);
1262     return GNUNET_OK;
1263   }
1264   tunnel_notify_connection_broken (c->t, GNUNET_PEER_search (&msg->peer1),
1265                                    GNUNET_PEER_search (&msg->peer2));
1266   return GNUNET_OK;
1267
1268 }
1269
1270
1271 /**
1272  * Core handler for tunnel destruction
1273  *
1274  * @param cls Closure (unused).
1275  * @param peer Peer identity of sending neighbor.
1276  * @param message Message.
1277  *
1278  * @return GNUNET_OK to keep the connection open,
1279  *         GNUNET_SYSERR to close it (signal serious error)
1280  */
1281 int
1282 GMC_handle_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
1283                     const struct GNUNET_MessageHeader *message)
1284 {
1285   struct GNUNET_MESH_ConnectionDestroy *msg;
1286   struct MeshConnection *c;
1287   GNUNET_PEER_Id id;
1288   int fwd;
1289
1290   msg = (struct GNUNET_MESH_ConnectionDestroy *) message;
1291   LOG (GNUNET_ERROR_TYPE_DEBUG,
1292               "Got a CONNECTION DESTROY message from %s\n",
1293               GNUNET_i2s (peer));
1294   LOG (GNUNET_ERROR_TYPE_DEBUG,
1295               "  for connection %s\n",
1296               GNUNET_h2s (&msg->cid));
1297   c = connection_get (&msg->cid);
1298   if (NULL == c)
1299   {
1300     /* Probably already got the message from another path,
1301      * destroyed the tunnel and retransmitted to children.
1302      * Safe to ignore.
1303      */
1304     GNUNET_STATISTICS_update (stats, "# control on unknown tunnel",
1305                               1, GNUNET_NO);
1306     return GNUNET_OK;
1307   }
1308   id = GNUNET_PEER_search (peer);
1309   if (id == connection_get_prev_hop (c)->id)
1310     fwd = GNUNET_YES;
1311   else if (id == connection_get_next_hop (c)->id)
1312     fwd = GNUNET_NO;
1313   else
1314   {
1315     GNUNET_break_op (0);
1316     return GNUNET_OK;
1317   }
1318   send_prebuilt_message_connection (message, c, NULL, fwd);
1319   c->destroy = GNUNET_YES;
1320
1321   return GNUNET_OK;
1322 }
1323
1324 /**
1325  * Generic handler for mesh network encrypted traffic.
1326  *
1327  * @param peer Peer identity this notification is about.
1328  * @param message Encrypted message.
1329  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1330  *
1331  * @return GNUNET_OK to keep the connection open,
1332  *         GNUNET_SYSERR to close it (signal serious error)
1333  */
1334 static int
1335 handle_mesh_encrypted (const struct GNUNET_PeerIdentity *peer,
1336                        const struct GNUNET_MESH_Encrypted *msg,
1337                        int fwd)
1338 {
1339   struct MeshConnection *c;
1340   struct MeshTunnel2 *t;
1341   struct MeshPeer *neighbor;
1342   struct MeshFlowControl *fc;
1343   uint32_t pid;
1344   uint32_t ttl;
1345   uint16_t type;
1346   size_t size;
1347
1348   /* Check size */
1349   size = ntohs (msg->header.size);
1350   if (size <
1351       sizeof (struct GNUNET_MESH_Encrypted) +
1352       sizeof (struct GNUNET_MessageHeader))
1353   {
1354     GNUNET_break_op (0);
1355     return GNUNET_OK;
1356   }
1357   type = ntohs (msg->header.type);
1358   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
1359   LOG (GNUNET_ERROR_TYPE_DEBUG, "got a %s message from %s\n",
1360               GNUNET_MESH_DEBUG_M2S (type), GNUNET_i2s (peer));
1361
1362   /* Check connection */
1363   c = connection_get (&msg->cid);
1364   if (NULL == c)
1365   {
1366     GNUNET_STATISTICS_update (stats, "# unknown connection", 1, GNUNET_NO);
1367     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING connection unknown\n");
1368     return GNUNET_OK;
1369   }
1370   t = c->t;
1371   fc = fwd ? &c->bck_fc : &c->fwd_fc;
1372
1373   /* Check if origin is as expected */
1374   neighbor = connection_get_hop (c, !fwd);
1375   if (peer_get (peer)->id != neighbor->id)
1376   {
1377     GNUNET_break_op (0);
1378     return GNUNET_OK;
1379   }
1380
1381   /* Check PID */
1382   pid = ntohl (msg->pid);
1383   if (GMC_is_pid_bigger (pid, fc->last_ack_sent))
1384   {
1385     GNUNET_STATISTICS_update (stats, "# unsolicited message", 1, GNUNET_NO);
1386     LOG (GNUNET_ERROR_TYPE_DEBUG,
1387                 "WARNING Received PID %u, (prev %u), ACK %u\n",
1388                 pid, fc->last_pid_recv, fc->last_ack_sent);
1389     return GNUNET_OK;
1390   }
1391   if (GNUNET_NO == GMC_is_pid_bigger (pid, fc->last_pid_recv))
1392   {
1393     GNUNET_STATISTICS_update (stats, "# duplicate PID", 1, GNUNET_NO);
1394     LOG (GNUNET_ERROR_TYPE_DEBUG,
1395                 " Pid %u not expected (%u+), dropping!\n",
1396                 pid, fc->last_pid_recv + 1);
1397     return GNUNET_OK;
1398   }
1399   if (MESH_CONNECTION_SENT == c->state)
1400     connection_change_state (c, MESH_CONNECTION_READY);
1401   connection_reset_timeout (c, fwd);
1402   fc->last_pid_recv = pid;
1403
1404   /* Is this message for us? */
1405   if (GMC_is_terminal (c, fwd))
1406   {
1407     size_t dsize = size - sizeof (struct GNUNET_MESH_Encrypted);
1408     char cbuf[dsize];
1409     struct GNUNET_MessageHeader *msgh;
1410     unsigned int off;
1411
1412     /* TODO signature verification */
1413     LOG (GNUNET_ERROR_TYPE_DEBUG, "  message for us!\n");
1414     GNUNET_STATISTICS_update (stats, "# messages received", 1, GNUNET_NO);
1415
1416     fc->last_pid_recv = pid;
1417     tunnel_decrypt (t, cbuf, &msg[1], dsize, msg->iv, fwd);
1418     off = 0;
1419     while (off < dsize)
1420     {
1421       msgh = (struct GNUNET_MessageHeader *) &cbuf[off];
1422       handle_decrypted (t, msgh, fwd);
1423       off += ntohs (msgh->size);
1424     }
1425     send_ack (c, NULL, fwd);
1426     return GNUNET_OK;
1427   }
1428
1429   /* Message not for us: forward to next hop */
1430   LOG (GNUNET_ERROR_TYPE_DEBUG, "  not for us, retransmitting...\n");
1431   ttl = ntohl (msg->ttl);
1432   LOG (GNUNET_ERROR_TYPE_DEBUG, "   ttl: %u\n", ttl);
1433   if (ttl == 0)
1434   {
1435     GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
1436     LOG (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
1437     send_ack (c, NULL, fwd);
1438     return GNUNET_OK;
1439   }
1440   GNUNET_STATISTICS_update (stats, "# messages forwarded", 1, GNUNET_NO);
1441
1442   send_prebuilt_message_connection (&msg->header, c, NULL, fwd);
1443
1444   return GNUNET_OK;
1445 }
1446
1447
1448 /**
1449  * Core handler for mesh network traffic going orig->dest.
1450  *
1451  * @param cls Closure (unused).
1452  * @param message Message received.
1453  * @param peer Peer who sent the message.
1454  *
1455  * @return GNUNET_OK to keep the connection open,
1456  *         GNUNET_SYSERR to close it (signal serious error)
1457  */
1458 int
1459 GMC_handle_fwd (void *cls, const struct GNUNET_PeerIdentity *peer,
1460                 const struct GNUNET_MessageHeader *message)
1461 {
1462   return handle_mesh_encrypted (peer,
1463                                 (struct GNUNET_MESH_Encrypted *)message,
1464                                 GNUNET_YES);
1465 }
1466
1467 /**
1468  * Core handler for mesh network traffic going dest->orig.
1469  *
1470  * @param cls Closure (unused).
1471  * @param message Message received.
1472  * @param peer Peer who sent the message.
1473  *
1474  * @return GNUNET_OK to keep the connection open,
1475  *         GNUNET_SYSERR to close it (signal serious error)
1476  */
1477 int
1478 GMC_handle_bck (void *cls, const struct GNUNET_PeerIdentity *peer,
1479                 const struct GNUNET_MessageHeader *message)
1480 {
1481   return handle_mesh_encrypted (peer,
1482                                 (struct GNUNET_MESH_Encrypted *)message,
1483                                 GNUNET_NO);
1484 }
1485
1486
1487 /**
1488  * Core handler for mesh network traffic point-to-point acks.
1489  *
1490  * @param cls closure
1491  * @param message message
1492  * @param peer peer identity this notification is about
1493  *
1494  * @return GNUNET_OK to keep the connection open,
1495  *         GNUNET_SYSERR to close it (signal serious error)
1496  */
1497 int
1498 GMC_handle_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
1499                 const struct GNUNET_MessageHeader *message)
1500 {
1501   struct GNUNET_MESH_ACK *msg;
1502   struct MeshConnection *c;
1503   struct MeshFlowControl *fc;
1504   GNUNET_PEER_Id id;
1505   uint32_t ack;
1506   int fwd;
1507
1508   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
1509   LOG (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK packet from %s!\n",
1510               GNUNET_i2s (peer));
1511   msg = (struct GNUNET_MESH_ACK *) message;
1512
1513   c = connection_get (&msg->cid);
1514
1515   if (NULL == c)
1516   {
1517     GNUNET_STATISTICS_update (stats, "# ack on unknown connection", 1,
1518                               GNUNET_NO);
1519     return GNUNET_OK;
1520   }
1521
1522   /* Is this a forward or backward ACK? */
1523   id = GNUNET_PEER_search (peer);
1524   if (connection_get_next_hop (c)->id == id)
1525   {
1526     LOG (GNUNET_ERROR_TYPE_DEBUG, "  FWD ACK\n");
1527     fc = &c->fwd_fc;
1528     fwd = GNUNET_YES;
1529   }
1530   else if (connection_get_prev_hop (c)->id == id)
1531   {
1532     LOG (GNUNET_ERROR_TYPE_DEBUG, "  BCK ACK\n");
1533     fc = &c->bck_fc;
1534     fwd = GNUNET_NO;
1535   }
1536   else
1537   {
1538     GNUNET_break_op (0);
1539     return GNUNET_OK;
1540   }
1541
1542   ack = ntohl (msg->ack);
1543   LOG (GNUNET_ERROR_TYPE_DEBUG, "  ACK %u (was %u)\n",
1544               ack, fc->last_ack_recv);
1545   if (GMC_is_pid_bigger (ack, fc->last_ack_recv))
1546     fc->last_ack_recv = ack;
1547
1548   /* Cancel polling if the ACK is big enough. */
1549   if (GNUNET_SCHEDULER_NO_TASK != fc->poll_task &&
1550       GMC_is_pid_bigger (fc->last_ack_recv, fc->last_pid_sent))
1551   {
1552     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Cancel poll\n");
1553     GNUNET_SCHEDULER_cancel (fc->poll_task);
1554     fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
1555     fc->poll_time = GNUNET_TIME_UNIT_SECONDS;
1556   }
1557
1558   connection_unlock_queue (c, fwd);
1559
1560   return GNUNET_OK;
1561 }
1562
1563
1564 /**
1565  * Core handler for mesh network traffic point-to-point ack polls.
1566  *
1567  * @param cls closure
1568  * @param message message
1569  * @param peer peer identity this notification is about
1570  *
1571  * @return GNUNET_OK to keep the connection open,
1572  *         GNUNET_SYSERR to close it (signal serious error)
1573  */
1574 int
1575 GMC_handle_poll (void *cls, const struct GNUNET_PeerIdentity *peer,
1576                  const struct GNUNET_MessageHeader *message)
1577 {
1578   struct GNUNET_MESH_Poll *msg;
1579   struct MeshConnection *c;
1580   struct MeshFlowControl *fc;
1581   GNUNET_PEER_Id id;
1582   uint32_t pid;
1583   int fwd;
1584
1585   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
1586   LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a POLL packet from %s!\n",
1587               GNUNET_i2s (peer));
1588
1589   msg = (struct GNUNET_MESH_Poll *) message;
1590
1591   c = connection_get (&msg->cid);
1592
1593   if (NULL == c)
1594   {
1595     GNUNET_STATISTICS_update (stats, "# poll on unknown connection", 1,
1596                               GNUNET_NO);
1597     GNUNET_break_op (0);
1598     return GNUNET_OK;
1599   }
1600
1601   /* Is this a forward or backward ACK?
1602    * Note: a poll should never be needed in a loopback case,
1603    * since there is no possiblility of packet loss there, so
1604    * this way of discerining FWD/BCK should not be a problem.
1605    */
1606   id = GNUNET_PEER_search (peer);
1607   if (connection_get_next_hop (c)->id == id)
1608   {
1609     LOG (GNUNET_ERROR_TYPE_DEBUG, "  FWD ACK\n");
1610     fc = &c->fwd_fc;
1611   }
1612   else if (connection_get_prev_hop (c)->id == id)
1613   {
1614     LOG (GNUNET_ERROR_TYPE_DEBUG, "  BCK ACK\n");
1615     fc = &c->bck_fc;
1616   }
1617   else
1618   {
1619     GNUNET_break_op (0);
1620     return GNUNET_OK;
1621   }
1622
1623   pid = ntohl (msg->pid);
1624   LOG (GNUNET_ERROR_TYPE_DEBUG, "  PID %u, OLD %u\n",
1625               pid, fc->last_pid_recv);
1626   fc->last_pid_recv = pid;
1627   fwd = fc == &c->fwd_fc;
1628   send_ack (c, NULL, fwd);
1629
1630   return GNUNET_OK;
1631 }
1632
1633
1634 /**
1635  * Core handler for mesh keepalives.
1636  *
1637  * @param cls closure
1638  * @param message message
1639  * @param peer peer identity this notification is about
1640  * @return GNUNET_OK to keep the connection open,
1641  *         GNUNET_SYSERR to close it (signal serious error)
1642  *
1643  * TODO: Check who we got this from, to validate route.
1644  */
1645 int
1646 GMC_handle_keepalive (void *cls, const struct GNUNET_PeerIdentity *peer,
1647                     const struct GNUNET_MessageHeader *message)
1648 {
1649   struct GNUNET_MESH_ConnectionKeepAlive *msg;
1650   struct MeshConnection *c;
1651   struct MeshPeer *neighbor;
1652   int fwd;
1653
1654   msg = (struct GNUNET_MESH_ConnectionKeepAlive *) message;
1655   LOG (GNUNET_ERROR_TYPE_DEBUG, "got a keepalive packet from %s\n",
1656               GNUNET_i2s (peer));
1657
1658   c = connection_get (&msg->cid);
1659   if (NULL == c)
1660   {
1661     GNUNET_STATISTICS_update (stats, "# keepalive on unknown connection", 1,
1662                               GNUNET_NO);
1663     return GNUNET_OK;
1664   }
1665
1666   fwd = GNUNET_MESSAGE_TYPE_MESH_FWD_KEEPALIVE == ntohs (message->type) ?
1667         GNUNET_YES : GNUNET_NO;
1668
1669   /* Check if origin is as expected */
1670   neighbor = connection_get_hop (c, fwd);
1671   if (peer_get (peer)->id != neighbor->id)
1672   {
1673     GNUNET_break_op (0);
1674     return GNUNET_OK;
1675   }
1676
1677   connection_change_state (c, MESH_CONNECTION_READY);
1678   connection_reset_timeout (c, fwd);
1679
1680   if (GMC_is_terminal (c, fwd))
1681     return GNUNET_OK;
1682
1683   GNUNET_STATISTICS_update (stats, "# keepalives forwarded", 1, GNUNET_NO);
1684   send_prebuilt_message_connection (message, c, NULL, fwd);
1685
1686   return GNUNET_OK;
1687 }
1688
1689
1690 /**
1691  * Send an ACK on the appropriate connection/channel, depending on
1692  * the direction and the position of the peer.
1693  *
1694  * @param c Which connection to send the hop-by-hop ACK.
1695  * @param ch Channel, if any.
1696  * @param fwd Is this a fwd ACK? (will go dest->root)
1697  */
1698 static void
1699 send_ack (struct MeshConnection *c, struct MeshChannel *ch, int fwd)
1700 {
1701   unsigned int buffer;
1702
1703   LOG (GNUNET_ERROR_TYPE_DEBUG,
1704               "send ack %s on %p %p\n",
1705               fwd ? "FWD" : "BCK", c, ch);
1706   if (NULL == c || GMC_is_terminal (c, fwd))
1707   {
1708     LOG (GNUNET_ERROR_TYPE_DEBUG, "  getting from all connections\n");
1709     buffer = tunnel_get_buffer (NULL == c ? ch->t : c->t, fwd);
1710   }
1711   else
1712   {
1713     LOG (GNUNET_ERROR_TYPE_DEBUG, "  getting from one connection\n");
1714     buffer = connection_get_buffer (c, fwd);
1715   }
1716   LOG (GNUNET_ERROR_TYPE_DEBUG, "  buffer available: %u\n", buffer);
1717
1718   if ( (NULL != ch && channel_is_origin (ch, fwd)) ||
1719        (NULL != c && connection_is_origin (c, fwd)) )
1720   {
1721     LOG (GNUNET_ERROR_TYPE_DEBUG, "  sending on channel...\n");
1722     if (0 < buffer)
1723     {
1724       GNUNET_assert (NULL != ch);
1725       LOG (GNUNET_ERROR_TYPE_DEBUG, "  really sending!\n");
1726       send_local_ack (ch, fwd);
1727     }
1728   }
1729   else if (NULL == c)
1730   {
1731     LOG (GNUNET_ERROR_TYPE_DEBUG, "  sending on all connections\n");
1732     GNUNET_assert (NULL != ch);
1733     channel_send_connections_ack (ch, buffer, fwd);
1734   }
1735   else
1736   {
1737     LOG (GNUNET_ERROR_TYPE_DEBUG, "  sending on connection\n");
1738     connection_send_ack (c, buffer, fwd);
1739   }
1740 }
1741
1742
1743
1744 /**
1745  * Initialize the connections subsystem
1746  *
1747  * @param c Configuration handle.
1748  */
1749 void
1750 GMC_init (const struct GNUNET_CONFIGURATION_Handle *c)
1751 {
1752   if (GNUNET_OK !=
1753       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_MSGS_QUEUE",
1754                                              &max_msgs_queue))
1755   {
1756     LOG_config_invalid (GNUNET_ERROR_TYPE_ERROR,
1757                                "MESH", "MAX_MSGS_QUEUE", "MISSING");
1758     GNUNET_SCHEDULER_shutdown ();
1759     return;
1760   }
1761
1762   if (GNUNET_OK !=
1763       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_CONNECTIONS",
1764                                              &max_connections))
1765   {
1766     LOG_config_invalid (GNUNET_ERROR_TYPE_ERROR,
1767                                "MESH", "MAX_CONNECTIONS", "MISSING");
1768     GNUNET_SCHEDULER_shutdown ();
1769     return;
1770   }
1771
1772   if (GNUNET_OK !=
1773       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "REFRESH_CONNECTION_TIME",
1774                                            &refresh_connection_time))
1775   {
1776     LOG_config_invalid (GNUNET_ERROR_TYPE_ERROR,
1777                                "MESH", "REFRESH_CONNECTION_TIME", "MISSING");
1778     GNUNET_SCHEDULER_shutdown ();
1779     return;
1780   }
1781   connections = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_YES);
1782 }
1783
1784 /**
1785  * Shut down the connections subsystem.
1786  */
1787 void
1788 GMC_shutdown (void)
1789 {
1790   if (core_handle != NULL)
1791   {
1792     GNUNET_CORE_disconnect (core_handle);
1793     core_handle = NULL;
1794   }
1795 }
1796
1797
1798 struct MeshConnection *
1799 GMC_new (const struct GNUNET_HashCode *cid)
1800 {
1801   struct MeshConnection *c;
1802   
1803   c = GNUNET_new (struct MeshConnection);
1804   c->id = *cid;
1805   GNUNET_CONTAINER_multihashmap_put (connections, &c->id, c,
1806                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1807   fc_init (&c->fwd_fc);
1808   fc_init (&c->bck_fc);
1809   c->fwd_fc.c = c;
1810   c->bck_fc.c = c;
1811   
1812   return c;
1813 }
1814
1815
1816 static void
1817 GMC_destroy (struct MeshConnection *c)
1818 {
1819   struct MeshPeer *peer;
1820
1821   if (NULL == c)
1822     return;
1823
1824   LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying connection %s[%X]\n",
1825               peer2s (c->t->peer),
1826               c->id);
1827
1828   /* Cancel all traffic */
1829   connection_cancel_queues (c, GNUNET_YES);
1830   connection_cancel_queues (c, GNUNET_NO);
1831
1832   /* Cancel maintainance task (keepalive/timeout) */
1833   if (GNUNET_SCHEDULER_NO_TASK != c->fwd_maintenance_task)
1834     GNUNET_SCHEDULER_cancel (c->fwd_maintenance_task);
1835   if (GNUNET_SCHEDULER_NO_TASK != c->bck_maintenance_task)
1836     GNUNET_SCHEDULER_cancel (c->bck_maintenance_task);
1837
1838   /* Deregister from neighbors */
1839   peer = connection_get_next_hop (c);
1840   if (NULL != peer && NULL != peer->connections)
1841     GNUNET_CONTAINER_multihashmap_remove (peer->connections, &c->id, c);
1842   peer = connection_get_prev_hop (c);
1843   if (NULL != peer && NULL != peer->connections)
1844     GNUNET_CONTAINER_multihashmap_remove (peer->connections, &c->id, c);
1845
1846   /* Delete */
1847   GNUNET_STATISTICS_update (stats, "# connections", -1, GNUNET_NO);
1848   GNUNET_CONTAINER_DLL_remove (c->t->connection_head, c->t->connection_tail, c);
1849   GNUNET_free (c);
1850 }
1851
1852
1853 /**
1854  * Notify other peers on a connection of a broken link. Mark connections
1855  * to destroy after all traffic has been sent.
1856  *
1857  * @param c Connection on which there has been a disconnection.
1858  * @param peer Peer that disconnected.
1859  * @param my_full_id My ID (to send to other peers).
1860  */
1861 void
1862 GMC_notify_broken (struct MeshConnection *c,
1863                    struct MeshPeer *peer,
1864                    struct GNUNET_PeerIdentity *my_full_id)
1865 {
1866   struct MeshConnection *c = value;
1867   struct GNUNET_MESH_ConnectionBroken msg;
1868   int fwd;
1869
1870   fwd = peer == connection_get_prev_hop (c);
1871
1872   connection_cancel_queues (c, !fwd);
1873   if (GMC_is_terminal (c, fwd))
1874   {
1875     /* Local shutdown, no one to notify about this. */
1876     GMC_destroy (c);
1877     return GNUNET_YES;
1878   }
1879
1880   msg.header.size = htons (sizeof (struct GNUNET_MESH_ConnectionBroken));
1881   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN);
1882   msg.cid = c->id;
1883   msg.peer1 = *my_full_id;
1884   msg.peer2 = *GNUNET_PEER_resolve2 (peer->id);
1885   GMC_send_prebuilt_message (&msg.header, c, NULL, fwd);
1886   c->destroy = GNUNET_YES;
1887
1888   return GNUNET_YES;
1889 }
1890
1891
1892 /**
1893  * Is this peer the first one on the connection?
1894  *
1895  * @param c Connection.
1896  * @param fwd Is this about fwd traffic?
1897  *
1898  * @return GNUNET_YES if origin, GNUNET_NO if relay/terminal.
1899  */
1900 int
1901 GMC_is_origin (struct MeshConnection *c, int fwd)
1902 {
1903   if (!fwd && c->path->length - 1 == c->own_pos )
1904     return GNUNET_YES;
1905   if (fwd && 0 == c->own_pos)
1906     return GNUNET_YES;
1907   return GNUNET_NO;
1908 }
1909
1910
1911 /**
1912  * Is this peer the last one on the connection?
1913  *
1914  * @param c Connection.
1915  * @param fwd Is this about fwd traffic?
1916  *            Note that the ROOT is the terminal for BCK traffic!
1917  *
1918  * @return GNUNET_YES if terminal, GNUNET_NO if relay/origin.
1919  */
1920 int
1921 GMC_is_terminal (struct MeshConnection *c, int fwd)
1922 {
1923   return GMC_is_origin (c, !fwd);
1924 }
1925
1926
1927 /**
1928  * Count connections in a DLL.
1929  */
1930 unsigned int
1931 GMC_count (const struct MeshConnection *head)
1932 {
1933   unsigned int count;
1934   struct MeshConnection *iter;
1935
1936   for (count = 0, iter = head; NULL != iter; iter = iter->next, count++);
1937
1938   return count;
1939 }
1940
1941
1942 /**
1943  * Sends an already built message on a connection, properly registering
1944  * all used resources.
1945  *
1946  * @param message Message to send. Function makes a copy of it.
1947  *                If message is not hop-by-hop, decrements TTL of copy.
1948  * @param c Connection on which this message is transmitted.
1949  * @param ch Channel on which this message is transmitted, or NULL.
1950  * @param fwd Is this a fwd message?
1951  */
1952 void
1953 GMC_send_prebuilt_message (    const struct GNUNET_MessageHeader *message,
1954                            struct MeshConnection *c,
1955                            struct MeshChannel *ch,
1956                            int fwd)
1957 {
1958   void *data;
1959   size_t size;
1960   uint16_t type;
1961
1962   size = ntohs (message->size);
1963   data = GNUNET_malloc (size);
1964   memcpy (data, message, size);
1965   type = ntohs (message->type);
1966   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send %s (%u) on connection %s\n",
1967               GNUNET_MESH_DEBUG_M2S (type), size, GNUNET_h2s (&c->id));
1968
1969   switch (type)
1970   {
1971     struct GNUNET_MESH_Encrypted *emsg;
1972     struct GNUNET_MESH_ACK       *amsg;
1973     struct GNUNET_MESH_Poll      *pmsg;
1974     struct GNUNET_MESH_ConnectionDestroy *dmsg;
1975     struct GNUNET_MESH_ConnectionBroken  *bmsg;
1976     uint32_t ttl;
1977
1978     case GNUNET_MESSAGE_TYPE_MESH_FWD:
1979     case GNUNET_MESSAGE_TYPE_MESH_BCK:
1980       emsg = (struct GNUNET_MESH_Encrypted *) data;
1981       ttl = ntohl (emsg->ttl);
1982       if (0 == ttl)
1983       {
1984         GNUNET_break_op (0);
1985         return;
1986       }
1987       emsg->cid = c->id;
1988       emsg->ttl = htonl (ttl - 1);
1989       emsg->pid = htonl (fwd ? c->fwd_fc.next_pid++ : c->bck_fc.next_pid++);
1990       LOG (GNUNET_ERROR_TYPE_DEBUG, " pid %u\n", ntohl (emsg->pid));
1991       break;
1992
1993     case GNUNET_MESSAGE_TYPE_MESH_ACK:
1994       amsg = (struct GNUNET_MESH_ACK *) data;
1995       amsg->cid = c->id;
1996       LOG (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ntohl (amsg->ack));
1997       break;
1998
1999     case GNUNET_MESSAGE_TYPE_MESH_POLL:
2000       pmsg = (struct GNUNET_MESH_Poll *) data;
2001       pmsg->cid = c->id;
2002       pmsg->pid = htonl (fwd ? c->fwd_fc.last_pid_sent : c->bck_fc.last_pid_sent);
2003       LOG (GNUNET_ERROR_TYPE_DEBUG, " poll %u\n", ntohl (pmsg->pid));
2004       break;
2005
2006     case GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY:
2007       dmsg = (struct GNUNET_MESH_ConnectionDestroy *) data;
2008       dmsg->cid = c->id;
2009       dmsg->reserved = 0;
2010       break;
2011
2012     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN:
2013       bmsg = (struct GNUNET_MESH_ConnectionBroken *) data;
2014       bmsg->cid = c->id;
2015       bmsg->reserved = 0;
2016       break;
2017
2018     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE:
2019     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK:
2020       break;
2021
2022     default:
2023       GNUNET_break (0);
2024   }
2025
2026   GMP_queue_add (data,
2027                  type,
2028                  size,
2029                  c,
2030                  ch,
2031                  fwd);
2032 }