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