- log
[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.h"
34 #include "mesh.h"
35 #include "gnunet-service-mesh_connection.h"
36 #include "gnunet-service-mesh_peer.h"
37 #include "gnunet-service-mesh_tunnel.h"
38
39
40 #define LOG(level, ...) GNUNET_log_from (level,"mesh-con",__VA_ARGS__)
41
42 #define MESH_MAX_POLL_TIME      GNUNET_TIME_relative_multiply (\
43                                   GNUNET_TIME_UNIT_MINUTES,\
44                                   10)
45 #define AVG_MSGS                32
46
47
48 /******************************************************************************/
49 /********************************   STRUCTS  **********************************/
50 /******************************************************************************/
51
52 /**
53  * Struct to encapsulate all the Flow Control information to a peer to which
54  * we are directly connected (on a core level).
55  */
56 struct MeshFlowControl
57 {
58   /**
59    * Connection this controls.
60    */
61   struct MeshConnection *c;
62
63   /**
64    * How many messages are in the queue on this connection.
65    */
66   unsigned int queue_n;
67
68   /**
69    * How many messages do we accept in the queue.
70    */
71   unsigned int queue_max;
72
73   /**
74    * Next ID to use.
75    */
76   uint32_t next_pid;
77
78   /**
79    * ID of the last packet sent towards the peer.
80    */
81   uint32_t last_pid_sent;
82
83   /**
84    * ID of the last packet received from the peer.
85    */
86   uint32_t last_pid_recv;
87
88   /**
89    * Last ACK sent to the peer (peer can't send more than this PID).
90    */
91   uint32_t last_ack_sent;
92
93   /**
94    * Last ACK sent towards the origin (for traffic towards leaf node).
95    */
96   uint32_t last_ack_recv;
97
98   /**
99    * Task to poll the peer in case of a lost ACK causes stall.
100    */
101   GNUNET_SCHEDULER_TaskIdentifier poll_task;
102
103   /**
104    * How frequently to poll for ACKs.
105    */
106   struct GNUNET_TIME_Relative poll_time;
107
108   /**
109    * Queued poll message, to cancel if not necessary anymore (got ACK).
110    */
111   struct MeshConnectionQueue *poll_msg;
112
113   /**
114    * Queued poll message, to cancel if not necessary anymore (got ACK).
115    */
116   struct MeshConnectionQueue *ack_msg;
117 };
118
119 /**
120  * Keep a record of the last messages sent on this connection.
121  */
122 struct MeshConnectionPerformance
123 {
124   /**
125    * Circular buffer for storing measurements.
126    */
127   double usecsperbyte[AVG_MSGS];
128
129   /**
130    * Running average of @c usecsperbyte.
131    */
132   double avg;
133
134   /**
135    * How many values of @c usecsperbyte are valid.
136    */
137   uint16_t size;
138
139   /**
140    * Index of the next "free" position in @c usecsperbyte.
141    */
142   uint16_t idx;
143 };
144
145
146 /**
147  * Struct containing all information regarding a connection to a peer.
148  */
149 struct MeshConnection
150 {
151   /**
152    * Tunnel this connection is part of.
153    */
154   struct MeshTunnel3 *t;
155
156   /**
157    * Flow control information for traffic fwd.
158    */
159   struct MeshFlowControl fwd_fc;
160
161   /**
162    * Flow control information for traffic bck.
163    */
164   struct MeshFlowControl bck_fc;
165
166   /**
167    * Measure connection performance on the endpoint.
168    */
169   struct MeshConnectionPerformance *perf;
170
171   /**
172    * ID of the connection.
173    */
174   struct GNUNET_HashCode id;
175
176   /**
177    * State of the connection.
178    */
179   enum MeshConnectionState state;
180
181   /**
182    * Path being used for the tunnel.
183    */
184   struct MeshPeerPath *path;
185
186   /**
187    * Position of the local peer in the path.
188    */
189   unsigned int own_pos;
190
191   /**
192    * Task to keep the used paths alive at the owner,
193    * time tunnel out on all the other peers.
194    */
195   GNUNET_SCHEDULER_TaskIdentifier fwd_maintenance_task;
196
197   /**
198    * Task to keep the used paths alive at the destination,
199    * time tunnel out on all the other peers.
200    */
201   GNUNET_SCHEDULER_TaskIdentifier bck_maintenance_task;
202
203   /**
204    * Pending message count.
205    */
206   int pending_messages;
207
208   /**
209    * Destroy flag: if true, destroy on last message.
210    */
211   int destroy;
212 };
213
214 /**
215  * Handle for messages queued but not yet sent.
216  */
217 struct MeshConnectionQueue
218 {
219   /**
220    * Peer queue handle, to cancel if necessary.
221    */
222   struct MeshPeerQueue *q;
223
224   /**
225    * Continuation to call once sent.
226    */
227   GMC_sent cont;
228
229   /**
230    * Closure for @c cont.
231    */
232   void *cont_cls;
233 };
234
235 /******************************************************************************/
236 /*******************************   GLOBALS  ***********************************/
237 /******************************************************************************/
238
239 /**
240  * Global handle to the statistics service.
241  */
242 extern struct GNUNET_STATISTICS_Handle *stats;
243
244 /**
245  * Local peer own ID (memory efficient handle).
246  */
247 extern GNUNET_PEER_Id myid;
248
249 /**
250  * Local peer own ID (full value).
251  */
252 extern struct GNUNET_PeerIdentity my_full_id;
253
254 /**
255  * Connections known, indexed by cid (MeshConnection).
256  */
257 static struct GNUNET_CONTAINER_MultiHashMap *connections;
258
259 /**
260  * How many connections are we willing to maintain.
261  * Local connections are always allowed, even if there are more connections than max.
262  */
263 static unsigned long long max_connections;
264
265 /**
266  * How many messages *in total* are we willing to queue, divide by number of
267  * connections to get connection queue size.
268  */
269 static unsigned long long max_msgs_queue;
270
271 /**
272  * How often to send path keepalives. Paths timeout after 4 missed.
273  */
274 static struct GNUNET_TIME_Relative refresh_connection_time;
275
276 /**
277  * How often to send path create / ACKs.
278  */
279 static struct GNUNET_TIME_Relative create_connection_time;
280
281
282 /******************************************************************************/
283 /********************************   STATIC  ***********************************/
284 /******************************************************************************/
285
286 #if 0 // avoid compiler warning for unused static function
287 static void
288 fc_debug (struct MeshFlowControl *fc)
289 {
290   LOG (GNUNET_ERROR_TYPE_DEBUG, "    IN: %u/%u\n",
291               fc->last_pid_recv, fc->last_ack_sent);
292   LOG (GNUNET_ERROR_TYPE_DEBUG, "    OUT: %u/%u\n",
293               fc->last_pid_sent, fc->last_ack_recv);
294   LOG (GNUNET_ERROR_TYPE_DEBUG, "    QUEUE: %u/%u\n",
295               fc->queue_n, fc->queue_max);
296 }
297
298 static void
299 connection_debug (struct MeshConnection *c)
300 {
301   if (NULL == c)
302   {
303     LOG (GNUNET_ERROR_TYPE_DEBUG, "*** DEBUG NULL CONNECTION ***\n");
304     return;
305   }
306   LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection %s:%X\n",
307               peer2s (c->t->peer), GMC_2s (c));
308   LOG (GNUNET_ERROR_TYPE_DEBUG, "  state: %u, pending msgs: %u\n",
309               c->state, c->pending_messages);
310   LOG (GNUNET_ERROR_TYPE_DEBUG, "  FWD FC\n");
311   fc_debug (&c->fwd_fc);
312   LOG (GNUNET_ERROR_TYPE_DEBUG, "  BCK FC\n");
313   fc_debug (&c->bck_fc);
314 }
315 #endif
316
317 /**
318  * Get string description for tunnel state.
319  *
320  * @param s Tunnel state.
321  *
322  * @return String representation.
323  */
324 static const char *
325 GMC_state2s (enum MeshConnectionState s)
326 {
327   switch (s)
328   {
329     case MESH_CONNECTION_NEW:
330       return "MESH_CONNECTION_NEW";
331     case MESH_CONNECTION_SENT:
332       return "MESH_CONNECTION_SENT";
333     case MESH_CONNECTION_ACK:
334       return "MESH_CONNECTION_ACK";
335     case MESH_CONNECTION_READY:
336       return "MESH_CONNECTION_READY";
337     default:
338       return "MESH_CONNECTION_STATE_ERROR";
339   }
340 }
341
342
343 /**
344  * Initialize a Flow Control structure to the initial state.
345  *
346  * @param fc Flow Control structure to initialize.
347  */
348 static void
349 fc_init (struct MeshFlowControl *fc)
350 {
351   fc->next_pid = 0;
352   fc->last_pid_sent = (uint32_t) -1; /* Next (expected) = 0 */
353   fc->last_pid_recv = (uint32_t) -1;
354   fc->last_ack_sent = (uint32_t) 0;
355   fc->last_ack_recv = (uint32_t) 0;
356   fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
357   fc->poll_time = GNUNET_TIME_UNIT_SECONDS;
358   fc->queue_n = 0;
359   fc->queue_max = (max_msgs_queue / max_connections) + 1;
360 }
361
362
363 /**
364  * Find a connection.
365  *
366  * @param cid Connection ID.
367  */
368 static struct MeshConnection *
369 connection_get (const struct GNUNET_HashCode *cid)
370 {
371   return GNUNET_CONTAINER_multihashmap_get (connections, cid);
372 }
373
374
375 static void
376 connection_change_state (struct MeshConnection* c,
377                          enum MeshConnectionState state)
378 {
379   LOG (GNUNET_ERROR_TYPE_DEBUG,
380               "Connection %s state was %s\n",
381               GMC_2s (c), GMC_state2s (c->state));
382   LOG (GNUNET_ERROR_TYPE_DEBUG,
383               "Connection %s state is now %s\n",
384               GMC_2s (c), GMC_state2s (state));
385   c->state = state;
386 }
387
388
389 /**
390  * Callback called when a queued ACK message is sent.
391  *
392  * @param cls Closure (FC).
393  * @param c Connection this message was on.
394  * @param q Queue handler this call invalidates.
395  * @param type Type of message sent.
396  * @param fwd Was this a FWD going message?
397  * @param size Size of the message.
398  */
399 static void
400 ack_sent (void *cls,
401           struct MeshConnection *c,
402           struct MeshConnectionQueue *q,
403           uint16_t type, int fwd, size_t size)
404 {
405   struct MeshFlowControl *fc = cls;
406
407   fc->ack_msg = NULL;
408 }
409
410
411 /**
412  * Send an ACK on the connection, informing the predecessor about
413  * the available buffer space. Should not be called in case the peer
414  * is origin (no predecessor) in the @c fwd direction.
415  *
416  * Note that for fwd ack, the FWD mean forward *traffic* (root->dest),
417  * the ACK itself goes "back" (dest->root).
418  *
419  * @param c Connection on which to send the ACK.
420  * @param buffer How much space free to advertise?
421  * @param fwd Is this FWD ACK? (Going dest -> root)
422  * @param force Don't optimize out.
423  */
424 static void
425 send_ack (struct MeshConnection *c, unsigned int buffer, int fwd, int force)
426 {
427   struct MeshFlowControl *next_fc;
428   struct MeshFlowControl *prev_fc;
429   struct GNUNET_MESH_ACK msg;
430   uint32_t ack;
431   int delta;
432
433   /* If origin, there is no connection to send ACKs. Wrong function! */
434   if (GMC_is_origin (c, fwd))
435   {
436     GNUNET_break (0);
437     return;
438   }
439
440   next_fc = fwd ? &c->fwd_fc : &c->bck_fc;
441   prev_fc = fwd ? &c->bck_fc : &c->fwd_fc;
442
443   LOG (GNUNET_ERROR_TYPE_DEBUG,
444               "connection send %s ack on %s\n",
445               fwd ? "FWD" : "BCK", GMC_2s (c));
446
447   /* Check if we need to transmit the ACK. */
448   delta = prev_fc->last_ack_sent - prev_fc->last_pid_recv;
449   if (3 < delta && buffer < delta && GNUNET_NO == force)
450   {
451     LOG (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, buffer > 3\n");
452     LOG (GNUNET_ERROR_TYPE_DEBUG,
453          "  last pid recv: %u, last ack sent: %u\n",
454          prev_fc->last_pid_recv, prev_fc->last_ack_sent);
455     return;
456   }
457
458   /* Ok, ACK might be necessary, what PID to ACK? */
459   ack = prev_fc->last_pid_recv + buffer;
460   LOG (GNUNET_ERROR_TYPE_DEBUG, " ACK %u\n", ack);
461   LOG (GNUNET_ERROR_TYPE_DEBUG,
462        " last pid %u, last ack %u, qmax %u, q %u\n",
463        prev_fc->last_pid_recv, prev_fc->last_ack_sent,
464        next_fc->queue_max, next_fc->queue_n);
465   if (ack == prev_fc->last_ack_sent && GNUNET_NO == force)
466   {
467     LOG (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, not needed\n");
468     return;
469   }
470
471   /* Check if message is already in queue */
472   if (NULL != prev_fc->ack_msg)
473   {
474     if (GMC_is_pid_bigger (ack, prev_fc->last_ack_sent))
475     {
476       LOG (GNUNET_ERROR_TYPE_DEBUG, " canceling old ACK\n");
477       GMC_cancel (prev_fc->ack_msg);
478       /* GMC_cancel triggers ack_sent(), which clears fc->ack_msg */
479     }
480     else
481     {
482       LOG (GNUNET_ERROR_TYPE_DEBUG, " same ACK already in queue\n");
483       return;
484     }
485   }
486
487   prev_fc->last_ack_sent = ack;
488
489   /* Build ACK message and send on connection */
490   msg.header.size = htons (sizeof (msg));
491   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ACK);
492   msg.ack = htonl (ack);
493   msg.cid = c->id;
494
495   prev_fc->ack_msg = GMC_send_prebuilt_message (&msg.header, c, !fwd,
496                                                 &ack_sent, prev_fc);
497 }
498
499
500 /**
501  * Callback called when a queued message is sent.
502  *
503  * Calculates the average time and connection packet tracking.
504  *
505  * @param cls Closure (ConnectionQueue Handle).
506  * @param c Connection this message was on.
507  * @param type Type of message sent.
508  * @param fwd Was this a FWD going message?
509  * @param size Size of the message.
510  * @param wait Time spent waiting for core (only the time for THIS message)
511  */
512 static void 
513 message_sent (void *cls,
514               struct MeshConnection *c, uint16_t type,
515               int fwd, size_t size,
516               struct GNUNET_TIME_Relative wait)
517 {
518   struct MeshConnectionPerformance *p;
519   struct MeshFlowControl *fc;
520   struct MeshConnectionQueue *q = cls;
521   double usecsperbyte;
522
523   fc = fwd ? &c->fwd_fc : &c->bck_fc;
524   LOG (GNUNET_ERROR_TYPE_DEBUG,
525        "!  sent %s %s\n",
526        fwd ? "FWD" : "BCK",
527        GNUNET_MESH_DEBUG_M2S (type));
528   LOG (GNUNET_ERROR_TYPE_DEBUG, "!  C_P- %p %u\n", c, c->pending_messages);
529   if (NULL != q)
530   {
531     if (NULL != q->cont)
532     {
533       LOG (GNUNET_ERROR_TYPE_DEBUG, "!  calling cont\n");
534       q->cont (q->cont_cls, c, q, type, fwd, size);
535     }
536     GNUNET_free (q);
537   }
538   c->pending_messages--;
539   if (GNUNET_YES == c->destroy && 0 == c->pending_messages)
540   {
541     LOG (GNUNET_ERROR_TYPE_DEBUG, "!  destroying connection!\n");
542     GMC_destroy (c);
543     return;
544   }
545   /* Send ACK if needed, after accounting for sent ID in fc->queue_n */
546   switch (type)
547   {
548     case GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED:
549       fc->last_pid_sent++;
550       LOG (GNUNET_ERROR_TYPE_DEBUG, "!  Q_N- %p %u\n", fc, fc->queue_n);
551       fc->queue_n--;
552       LOG (GNUNET_ERROR_TYPE_DEBUG,
553            "!   accounting pid %u\n",
554            fc->last_pid_sent);
555       GMC_send_ack (c, fwd, GNUNET_NO);
556       break;
557
558     case GNUNET_MESSAGE_TYPE_MESH_POLL:
559       fc->poll_msg = NULL;
560       break;
561
562     case GNUNET_MESSAGE_TYPE_MESH_ACK:
563       fc->ack_msg = NULL;
564       break;
565
566     default:
567       break;
568   }
569   LOG (GNUNET_ERROR_TYPE_DEBUG, "!  message sent!\n");
570
571   if (NULL == c->perf)
572     return; /* Only endpoints are interested in timing. */
573
574   p = c->perf;
575   usecsperbyte = ((double) wait.rel_value_us) / size;
576   if (p->size == AVG_MSGS)
577   {
578     /* Array is full. Substract oldest value, add new one and store. */
579     p->avg -= (p->usecsperbyte[p->idx] / AVG_MSGS);
580     p->usecsperbyte[p->idx] = usecsperbyte;
581     p->avg += (p->usecsperbyte[p->idx] / AVG_MSGS);
582   }
583   else
584   {
585     /* Array not yet full. Add current value to avg and store. */
586     p->usecsperbyte[p->idx] = usecsperbyte;
587     p->avg *= p->size;
588     p->avg += p->usecsperbyte[p->idx];
589     p->size++;
590     p->avg /= p->size;
591   }
592   p->idx = (p->idx + 1) % AVG_MSGS;
593 }
594
595
596 /**
597  * Get the previous hop in a connection
598  *
599  * @param c Connection.
600  *
601  * @return Previous peer in the connection.
602  */
603 static struct MeshPeer *
604 get_prev_hop (const struct MeshConnection *c)
605 {
606   GNUNET_PEER_Id id;
607
608   LOG (GNUNET_ERROR_TYPE_DEBUG, "Get prev hop, own pos %u\n", c->own_pos);
609   if (0 == c->own_pos || c->path->length < 2)
610     id = c->path->peers[0];
611   else
612     id = c->path->peers[c->own_pos - 1];
613
614   return GMP_get_short (id);
615 }
616
617
618 /**
619  * Get the next hop in a connection
620  *
621  * @param c Connection.
622  *
623  * @return Next peer in the connection.
624  */
625 static struct MeshPeer *
626 get_next_hop (const struct MeshConnection *c)
627 {
628   GNUNET_PEER_Id id;
629
630   if ((c->path->length - 1) == c->own_pos || c->path->length < 2)
631     id = c->path->peers[c->path->length - 1];
632   else
633     id = c->path->peers[c->own_pos + 1];
634
635   return GMP_get_short (id);
636 }
637
638
639 /**
640  * Get the hop in a connection.
641  *
642  * @param c Connection.
643  * @param fwd Next hop?
644  *
645  * @return Next peer in the connection.
646  */
647 static struct MeshPeer *
648 get_hop (struct MeshConnection *c, int fwd)
649 {
650   if (fwd)
651     return get_next_hop (c);
652   return get_prev_hop (c);
653 }
654
655
656 /**
657  * Is traffic coming from this sender 'FWD' traffic?
658  *
659  * @param c Connection to check.
660  * @param sender Peer identity of neighbor.
661  *
662  * @return #GNUNET_YES in case the sender is the 'prev' hop and therefore
663  *         the traffic is 'FWD'.
664  *         #GNUNET_NO for BCK.
665  *         #GNUNET_SYSERR for errors.
666  */
667 static int 
668 is_fwd (const struct MeshConnection *c,
669         const struct GNUNET_PeerIdentity *sender)
670 {
671   GNUNET_PEER_Id id;
672
673   id = GNUNET_PEER_search (sender);
674   if (GMP_get_short_id (get_prev_hop (c)) == id)
675     return GNUNET_YES;
676
677   if (GMP_get_short_id (get_next_hop (c)) == id)
678     return GNUNET_NO;
679
680   GNUNET_break (0);
681   return GNUNET_SYSERR;
682 }
683
684
685 /**
686  * Sends a CONNECTION ACK message in reponse to a received CONNECTION_CREATE
687  * or a first CONNECTION_ACK directed to us.
688  *
689  * @param connection Connection to confirm.
690  * @param fwd Should we send it FWD? (root->dest)
691  *            (First (~SYNACK) goes BCK, second (~ACK) goes FWD)
692  */
693 static void
694 send_connection_ack (struct MeshConnection *connection, int fwd)
695 {
696   struct MeshTunnel3 *t;
697
698   t = connection->t;
699   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send connection %s ACK\n",
700        !fwd ? "FWD" : "BCK");
701   GMP_queue_add (get_hop (connection, fwd), NULL,
702                  GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK,
703                  sizeof (struct GNUNET_MESH_ConnectionACK),
704                  connection, fwd, &message_sent, NULL);
705   connection->pending_messages++;
706   if (MESH_TUNNEL3_NEW == GMT_get_state (t))
707     GMT_change_state (t, MESH_TUNNEL3_WAITING);
708   if (MESH_CONNECTION_READY != connection->state)
709     connection_change_state (connection, MESH_CONNECTION_SENT);
710 }
711
712
713 /**
714  * Send a notification that a connection is broken.
715  *
716  * @param c Connection that is broken.
717  * @param id1 Peer that has disconnected.
718  * @param id2 Peer that has disconnected.
719  * @param fwd Direction towards which to send it.
720  */
721 static void
722 send_broken (struct MeshConnection *c,
723              const struct GNUNET_PeerIdentity *id1,
724              const struct GNUNET_PeerIdentity *id2,
725              int fwd)
726 {
727   struct GNUNET_MESH_ConnectionBroken msg;
728
729   msg.header.size = htons (sizeof (struct GNUNET_MESH_ConnectionBroken));
730   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN);
731   msg.cid = c->id;
732   msg.peer1 = *id1;
733   msg.peer2 = *id2;
734   GMC_send_prebuilt_message (&msg.header, c, fwd, NULL, NULL);
735 }
736
737
738
739 /**
740  * Send keepalive packets for a connection.
741  *
742  * @param c Connection to keep alive..
743  * @param fwd Is this a FWD keepalive? (owner -> dest).
744  * 
745  * FIXME use only one type, register in GMC_send_prebuilt_message()
746  */
747 static void
748 connection_keepalive (struct MeshConnection *c, int fwd)
749 {
750   struct GNUNET_MESH_ConnectionKeepAlive *msg;
751   size_t size = sizeof (struct GNUNET_MESH_ConnectionKeepAlive);
752   char cbuf[size];
753   uint16_t type;
754
755   type = fwd ? GNUNET_MESSAGE_TYPE_MESH_FWD_KEEPALIVE :
756                GNUNET_MESSAGE_TYPE_MESH_BCK_KEEPALIVE;
757
758   LOG (GNUNET_ERROR_TYPE_DEBUG,
759        "sending %s keepalive for connection %s]\n",
760        fwd ? "FWD" : "BCK", GMC_2s (c));
761
762   msg = (struct GNUNET_MESH_ConnectionKeepAlive *) cbuf;
763   msg->header.size = htons (size);
764   msg->header.type = htons (type);
765   msg->cid = c->id;
766
767   GMC_send_prebuilt_message (&msg->header, c, fwd, NULL, NULL);
768 }
769
770
771 /**
772  * Send CONNECTION_{CREATE/ACK} packets for a connection.
773  *
774  * @param c Connection for which to send the message.
775  * @param fwd If #GNUNET_YES, send CREATE, otherwise send ACK.
776  */
777 static void
778 connection_recreate (struct MeshConnection *c, int fwd)
779 {
780   LOG (GNUNET_ERROR_TYPE_DEBUG, "sending connection recreate\n");
781   if (fwd)
782     GMC_send_create (c);
783   else
784     send_connection_ack (c, GNUNET_NO);
785 }
786
787
788 /**
789  * Generic connection timer management.
790  * Depending on the role of the peer in the connection will send the
791  * appropriate message (build or keepalive)
792  *
793  * @param c Conncetion to maintain.
794  * @param fwd Is FWD?
795  */
796 static void
797 connection_maintain (struct MeshConnection *c, int fwd)
798 {
799   if (MESH_TUNNEL3_SEARCHING == GMT_get_state (c->t))
800   {
801     /* TODO DHT GET with RO_BART */
802     return;
803   }
804   switch (c->state)
805   {
806     case MESH_CONNECTION_NEW:
807       GNUNET_break (0);
808       /* fall-through */
809     case MESH_CONNECTION_SENT:
810       connection_recreate (c, fwd);
811       break;
812     case MESH_CONNECTION_READY:
813       connection_keepalive (c, fwd);
814       break;
815     default:
816       break;
817   }
818 }
819
820
821 static void
822 connection_fwd_keepalive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
823 {
824   struct MeshConnection *c = cls;
825   struct GNUNET_TIME_Relative delay;
826
827   c->fwd_maintenance_task = GNUNET_SCHEDULER_NO_TASK;
828   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
829     return;
830
831   connection_maintain (c, GNUNET_YES);
832   delay = c->state == MESH_CONNECTION_READY ?
833           refresh_connection_time : create_connection_time;
834   c->fwd_maintenance_task = GNUNET_SCHEDULER_add_delayed (delay,
835                                                           &connection_fwd_keepalive,
836                                                           c);
837 }
838
839
840 static void
841 connection_bck_keepalive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
842 {
843   struct MeshConnection *c = cls;
844   struct GNUNET_TIME_Relative delay;
845
846   c->bck_maintenance_task = GNUNET_SCHEDULER_NO_TASK;
847   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
848     return;
849
850   connection_maintain (c, GNUNET_NO);
851   delay = c->state == MESH_CONNECTION_READY ?
852           refresh_connection_time : create_connection_time;
853   c->bck_maintenance_task = GNUNET_SCHEDULER_add_delayed (delay,
854                                                           &connection_bck_keepalive,
855                                                           c);
856 }
857
858
859 /**
860  * @brief Re-initiate traffic on this connection if necessary.
861  *
862  * Check if there is traffic queued towards this peer
863  * and the core transmit handle is NULL (traffic was stalled).
864  * If so, call core tmt rdy.
865  *
866  * @param c Connection on which initiate traffic.
867  * @param fwd Is this about fwd traffic?
868  */
869 static void
870 connection_unlock_queue (struct MeshConnection *c, int fwd)
871 {
872   struct MeshPeer *peer;
873
874   LOG (GNUNET_ERROR_TYPE_DEBUG,
875               "connection_unlock_queue %s on %s\n",
876               fwd ? "FWD" : "BCK", GMC_2s (c));
877
878   if (GMC_is_terminal (c, fwd))
879   {
880     LOG (GNUNET_ERROR_TYPE_DEBUG, " is terminal!\n");
881     return;
882   }
883
884   peer = get_hop (c, fwd);
885   GMP_queue_unlock (peer, c);
886 }
887
888
889 /**
890  * Cancel all transmissions that belong to a certain connection.
891  * 
892  * If the connection is scheduled for destruction and no more messages are left,
893  * the connection will be destroyed by the continuation call.
894  *
895  * @param c Connection which to cancel. Might be destroyed during this call.
896  * @param fwd Cancel fwd traffic?
897  */
898 static void
899 connection_cancel_queues (struct MeshConnection *c, int fwd)
900 {
901   struct MeshFlowControl *fc;
902   struct MeshPeer *peer;
903
904   LOG (GNUNET_ERROR_TYPE_DEBUG,
905        " *** Cancel %s queues for connection %s\n",
906        fwd ? "FWD" : "BCK", GMC_2s (c));
907   if (NULL == c)
908   {
909     GNUNET_break (0);
910     return;
911   }
912
913   fc = fwd ? &c->fwd_fc : &c->bck_fc;
914   if (GNUNET_SCHEDULER_NO_TASK != fc->poll_task)
915   {
916     GNUNET_SCHEDULER_cancel (fc->poll_task);
917     fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
918     LOG (GNUNET_ERROR_TYPE_DEBUG, " *** Cancel POLL in ccq for fc %p\n", fc);
919   }
920   peer = get_hop (c, fwd);
921   GMP_queue_cancel (peer, c);
922 }
923
924
925 /**
926  * Function called if a connection has been stalled for a while,
927  * possibly due to a missed ACK. Poll the neighbor about its ACK status.
928  *
929  * @param cls Closure (poll ctx).
930  * @param tc TaskContext.
931  */
932 static void
933 connection_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
934
935
936 /**
937  * Callback called when a queued POLL message is sent.
938  *
939  * @param cls Closure (FC).
940  * @param c Connection this message was on.
941  * @param q Queue handler this call invalidates.
942  * @param type Type of message sent.
943  * @param fwd Was this a FWD going message?
944  * @param size Size of the message.
945  */
946 static void
947 poll_sent (void *cls,
948            struct MeshConnection *c,
949            struct MeshConnectionQueue *q,
950            uint16_t type, int fwd, size_t size)
951 {
952   struct MeshFlowControl *fc = cls;
953
954   if (2 == c->destroy)
955   {
956     LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL canceled on shutdown\n");
957     return;
958   }
959   LOG (GNUNET_ERROR_TYPE_DEBUG,
960        " *** POLL sent for , scheduling new one!\n");
961   fc->poll_msg = NULL;
962   fc->poll_time = GNUNET_TIME_STD_BACKOFF (fc->poll_time);
963   fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
964                                                 &connection_poll, fc);
965   LOG (GNUNET_ERROR_TYPE_DEBUG, " task %u\n", fc->poll_task);
966   
967 }
968
969 /**
970  * Function called if a connection has been stalled for a while,
971  * possibly due to a missed ACK. Poll the neighbor about its ACK status.
972  *
973  * @param cls Closure (poll ctx).
974  * @param tc TaskContext.
975  */
976 static void
977 connection_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
978 {
979   struct MeshFlowControl *fc = cls;
980   struct GNUNET_MESH_Poll msg;
981   struct MeshConnection *c;
982
983   fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
984   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
985   {
986     return;
987   }
988
989   c = fc->c;
990   LOG (GNUNET_ERROR_TYPE_DEBUG, " *** Polling!\n");
991   LOG (GNUNET_ERROR_TYPE_DEBUG, " *** connection [%s]\n", GMC_2s (c));
992   LOG (GNUNET_ERROR_TYPE_DEBUG, " ***   %s\n",
993        fc == &c->fwd_fc ? "FWD" : "BCK");
994
995   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL);
996   msg.header.size = htons (sizeof (msg));
997   msg.pid = htonl (fc->last_pid_sent);
998   LOG (GNUNET_ERROR_TYPE_DEBUG, " *** last pid sent: %u!\n", fc->last_pid_sent);
999   fc->poll_msg = GMC_send_prebuilt_message (&msg.header, c, fc == &c->fwd_fc,
1000                                             &poll_sent, fc);
1001 }
1002
1003
1004 /**
1005  * Timeout function due to lack of keepalive/traffic from the owner.
1006  * Destroys connection if called.
1007  *
1008  * @param cls Closure (connection to destroy).
1009  * @param tc TaskContext.
1010  */
1011 static void
1012 connection_fwd_timeout (void *cls,
1013                         const struct GNUNET_SCHEDULER_TaskContext *tc)
1014 {
1015   struct MeshConnection *c = cls;
1016
1017   c->fwd_maintenance_task = GNUNET_SCHEDULER_NO_TASK;
1018   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
1019     return;
1020   LOG (GNUNET_ERROR_TYPE_DEBUG,
1021               "Connection %s[%X] FWD timed out. Destroying.\n",
1022               GMT_2s (c->t),
1023               c->id);
1024
1025   if (GMC_is_origin (c, GNUNET_YES)) /* If local, leave. */
1026     return;
1027
1028   GMC_destroy (c);
1029 }
1030
1031
1032 /**
1033  * Timeout function due to lack of keepalive/traffic from the destination.
1034  * Destroys connection if called.
1035  *
1036  * @param cls Closure (connection to destroy).
1037  * @param tc TaskContext
1038  */
1039 static void
1040 connection_bck_timeout (void *cls,
1041                         const struct GNUNET_SCHEDULER_TaskContext *tc)
1042 {
1043   struct MeshConnection *c = cls;
1044
1045   c->bck_maintenance_task = GNUNET_SCHEDULER_NO_TASK;
1046   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
1047     return;
1048
1049   LOG (GNUNET_ERROR_TYPE_DEBUG,
1050               "Connection %s[%X] FWD timed out. Destroying.\n",
1051               GMT_2s (c->t), c->id);
1052
1053   if (GMC_is_origin (c, GNUNET_NO)) /* If local, leave. */
1054     return;
1055
1056   GMC_destroy (c);
1057 }
1058
1059
1060 /**
1061  * Resets the connection timeout task, some other message has done the
1062  * task's job.
1063  * - For the first peer on the direction this means to send
1064  *   a keepalive or a path confirmation message (either create or ACK).
1065  * - For all other peers, this means to destroy the connection,
1066  *   due to lack of activity.
1067  * Starts the tiemout if no timeout was running (connection just created).
1068  *
1069  * @param c Connection whose timeout to reset.
1070  * @param fwd Is this forward?
1071  *
1072  * TODO use heap to improve efficiency of scheduler.
1073  */
1074 static void
1075 connection_reset_timeout (struct MeshConnection *c, int fwd)
1076 {
1077   GNUNET_SCHEDULER_TaskIdentifier *ti;
1078   GNUNET_SCHEDULER_Task f;
1079
1080   ti = fwd ? &c->fwd_maintenance_task : &c->bck_maintenance_task;
1081
1082   if (GNUNET_SCHEDULER_NO_TASK != *ti)
1083     GNUNET_SCHEDULER_cancel (*ti);
1084
1085   if (GMC_is_origin (c, fwd)) /* Startpoint */
1086   {
1087     f  = fwd ? &connection_fwd_keepalive : &connection_bck_keepalive;
1088     *ti = GNUNET_SCHEDULER_add_delayed (refresh_connection_time, f, c);
1089   }
1090   else /* Relay, endpoint. */
1091   {
1092     struct GNUNET_TIME_Relative delay;
1093
1094     delay = GNUNET_TIME_relative_multiply (refresh_connection_time, 4);
1095     f  = fwd ? &connection_fwd_timeout : &connection_bck_timeout;
1096     *ti = GNUNET_SCHEDULER_add_delayed (delay, f, c);
1097   }
1098 }
1099
1100
1101 /**
1102  * Add the connection to the list of both neighbors.
1103  *
1104  * @param c Connection.
1105  *
1106  * @return #GNUNET_OK if everything went fine
1107  *         #GNUNET_SYSERR if the was an error and @c c is malformed.
1108  */
1109 static int
1110 register_neighbors (struct MeshConnection *c)
1111 {
1112   struct MeshPeer *next_peer;
1113   struct MeshPeer *prev_peer;
1114
1115   next_peer = get_next_hop (c);
1116   prev_peer = get_prev_hop (c);
1117
1118   if (GNUNET_NO == GMP_is_neighbor (next_peer)
1119       || GNUNET_NO == GMP_is_neighbor (prev_peer))
1120     return GNUNET_SYSERR;
1121
1122   GMP_add_connection (next_peer, c);
1123   GMP_add_connection (prev_peer, c);
1124
1125   return GNUNET_OK;
1126 }
1127
1128
1129 /**
1130  * Remove the connection from the list of both neighbors.
1131  *
1132  * @param c Connection.
1133  */
1134 static void
1135 unregister_neighbors (struct MeshConnection *c)
1136 {
1137   struct MeshPeer *peer;
1138
1139   peer = get_next_hop (c);
1140   GMP_remove_connection (peer, c);
1141
1142   peer = get_prev_hop (c);
1143   GMP_remove_connection (peer, c);
1144
1145 }
1146
1147
1148 /**
1149  * Bind the connection to the peer and the tunnel to that peer.
1150  *
1151  * If the peer has no tunnel, create one. Update tunnel and connection
1152  * data structres to reflect new status.
1153  *
1154  * @param c Connection.
1155  * @param peer Peer.
1156  */
1157 static void
1158 add_to_peer (struct MeshConnection *c, struct MeshPeer *peer)
1159 {
1160   GMP_add_tunnel (peer);
1161   c->t = GMP_get_tunnel (peer);
1162   GMT_add_connection (c->t, c);
1163 }
1164
1165 /******************************************************************************/
1166 /********************************    API    ***********************************/
1167 /******************************************************************************/
1168
1169 /**
1170  * Core handler for connection creation.
1171  *
1172  * @param cls Closure (unused).
1173  * @param peer Sender (neighbor).
1174  * @param message Message.
1175  *
1176  * @return GNUNET_OK to keep the connection open,
1177  *         GNUNET_SYSERR to close it (signal serious error)
1178  */
1179 int
1180 GMC_handle_create (void *cls, const struct GNUNET_PeerIdentity *peer,
1181                    const struct GNUNET_MessageHeader *message)
1182 {
1183   struct GNUNET_MESH_ConnectionCreate *msg;
1184   struct GNUNET_PeerIdentity *id;
1185   struct GNUNET_HashCode *cid;
1186   struct MeshPeerPath *path;
1187   struct MeshPeer *dest_peer;
1188   struct MeshPeer *orig_peer;
1189   struct MeshConnection *c;
1190   unsigned int own_pos;
1191   uint16_t size;
1192   uint16_t i;
1193
1194   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
1195   LOG (GNUNET_ERROR_TYPE_DEBUG, "Received a connection create msg\n");
1196
1197   /* Check size */
1198   size = ntohs (message->size);
1199   if (size < sizeof (struct GNUNET_MESH_ConnectionCreate))
1200   {
1201     GNUNET_break_op (0);
1202     return GNUNET_OK;
1203   }
1204
1205   /* Calculate hops */
1206   size -= sizeof (struct GNUNET_MESH_ConnectionCreate);
1207   if (size % sizeof (struct GNUNET_PeerIdentity))
1208   {
1209     GNUNET_break_op (0);
1210     return GNUNET_OK;
1211   }
1212   size /= sizeof (struct GNUNET_PeerIdentity);
1213   if (1 > size)
1214   {
1215     GNUNET_break_op (0);
1216     return GNUNET_OK;
1217   }
1218   LOG (GNUNET_ERROR_TYPE_DEBUG, "    path has %u hops.\n", size);
1219
1220   /* Get parameters */
1221   msg = (struct GNUNET_MESH_ConnectionCreate *) message;
1222   cid = &msg->cid;
1223   id = (struct GNUNET_PeerIdentity *) &msg[1];
1224   LOG (GNUNET_ERROR_TYPE_DEBUG,
1225               "    connection %s (%s).\n",
1226               GNUNET_h2s (cid), GNUNET_i2s (id));
1227
1228   /* Create connection */
1229   c = connection_get (cid);
1230   if (NULL == c)
1231   {
1232     /* Create path */
1233     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Creating path...\n");
1234     path = path_new (size);
1235     own_pos = 0;
1236     for (i = 0; i < size; i++)
1237     {
1238       LOG (GNUNET_ERROR_TYPE_DEBUG, "  ... adding %s\n",
1239                   GNUNET_i2s (&id[i]));
1240       path->peers[i] = GNUNET_PEER_intern (&id[i]);
1241       if (path->peers[i] == myid)
1242         own_pos = i;
1243     }
1244     if (own_pos == 0 && path->peers[own_pos] != myid)
1245     {
1246       /* create path: self not found in path through self */
1247       GNUNET_break_op (0);
1248       path_destroy (path);
1249       return GNUNET_OK;
1250     }
1251     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Own position: %u\n", own_pos);
1252     GMP_add_path_to_all (path, GNUNET_NO);
1253         LOG (GNUNET_ERROR_TYPE_DEBUG, "  Creating connection\n");
1254     c = GMC_new (cid, NULL, path_duplicate (path), own_pos);
1255     if (NULL == c)
1256     {
1257       path_destroy (path);
1258       return GNUNET_OK;
1259     }
1260     connection_reset_timeout (c, GNUNET_YES);
1261   }
1262   else
1263   {
1264     path = path_duplicate (c->path);
1265   }
1266   if (MESH_CONNECTION_NEW == c->state)
1267     connection_change_state (c, MESH_CONNECTION_SENT);
1268
1269   /* Remember peers */
1270   dest_peer = GMP_get (&id[size - 1]);
1271   orig_peer = GMP_get (&id[0]);
1272
1273   /* Is it a connection to us? */
1274   if (c->own_pos == size - 1)
1275   {
1276     LOG (GNUNET_ERROR_TYPE_DEBUG, "  It's for us!\n");
1277     GMP_add_path_to_origin (orig_peer, path, GNUNET_YES);
1278
1279     add_to_peer (c, orig_peer);
1280     if (MESH_TUNNEL3_NEW == GMT_get_state (c->t))
1281       GMT_change_state (c->t,  MESH_TUNNEL3_WAITING);
1282
1283     send_connection_ack (c, GNUNET_NO);
1284     if (MESH_CONNECTION_SENT == c->state)
1285       connection_change_state (c, MESH_CONNECTION_ACK);
1286
1287     /* Keep tunnel alive in direction dest->owner*/
1288     c->bck_maintenance_task =
1289             GNUNET_SCHEDULER_add_delayed (create_connection_time,
1290                                           &connection_bck_keepalive, c);
1291   }
1292   else
1293   {
1294     /* It's for somebody else! Retransmit. */
1295     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Retransmitting.\n");
1296     GMP_add_path (dest_peer, path_duplicate (path), GNUNET_NO);
1297     GMP_add_path_to_origin (orig_peer, path_duplicate (path), GNUNET_NO);
1298     GMC_send_prebuilt_message (message, c, GNUNET_YES, NULL, NULL);
1299   }
1300   path_destroy (path);
1301   return GNUNET_OK;
1302 }
1303
1304
1305 /**
1306  * Core handler for path confirmations.
1307  *
1308  * @param cls closure
1309  * @param message message
1310  * @param peer peer identity this notification is about
1311  *
1312  * @return GNUNET_OK to keep the connection open,
1313  *         GNUNET_SYSERR to close it (signal serious error)
1314  */
1315 int
1316 GMC_handle_confirm (void *cls, const struct GNUNET_PeerIdentity *peer,
1317                     const struct GNUNET_MessageHeader *message)
1318 {
1319   struct GNUNET_MESH_ConnectionACK *msg;
1320   struct MeshConnection *c;
1321   struct MeshPeerPath *p;
1322   struct MeshPeer *pi;
1323   enum MeshConnectionState oldstate;
1324   int fwd;
1325
1326   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
1327   LOG (GNUNET_ERROR_TYPE_DEBUG, "Received a connection ACK msg\n");
1328   msg = (struct GNUNET_MESH_ConnectionACK *) message;
1329   LOG (GNUNET_ERROR_TYPE_DEBUG, "  on connection %s\n",
1330               GNUNET_h2s (&msg->cid));
1331   c = connection_get (&msg->cid);
1332   if (NULL == c)
1333   {
1334     GNUNET_STATISTICS_update (stats, "# control on unknown connection",
1335                               1, GNUNET_NO);
1336     LOG (GNUNET_ERROR_TYPE_DEBUG, "  don't know the connection!\n");
1337     return GNUNET_OK;
1338   }
1339
1340   oldstate = c->state;
1341   LOG (GNUNET_ERROR_TYPE_DEBUG, "  via peer %s\n", GNUNET_i2s (peer));
1342   pi = GMP_get (peer);
1343   if (get_next_hop (c) == pi)
1344   {
1345     LOG (GNUNET_ERROR_TYPE_DEBUG, "  SYNACK\n");
1346     fwd = GNUNET_NO;
1347     if (MESH_CONNECTION_SENT == oldstate)
1348       connection_change_state (c, MESH_CONNECTION_ACK);
1349   }
1350   else if (get_prev_hop (c) == pi)
1351   {
1352     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ACK\n");
1353     fwd = GNUNET_YES;
1354     connection_change_state (c, MESH_CONNECTION_READY);
1355   }
1356   else
1357   {
1358     GNUNET_break_op (0);
1359     return GNUNET_OK;
1360   }
1361
1362   connection_reset_timeout (c, fwd);
1363
1364   /* Add path to peers? */
1365   p = c->path;
1366   if (NULL != p)
1367   {
1368     GMP_add_path_to_all (p, GNUNET_YES);
1369   }
1370   else
1371   {
1372     GNUNET_break (0);
1373   }
1374
1375   /* Message for us as creator? */
1376   if (GMC_is_origin (c, GNUNET_YES))
1377   {
1378     if (GNUNET_NO != fwd)
1379     {
1380       GNUNET_break_op (0);
1381       return GNUNET_OK;
1382     }
1383     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Connection (SYN)ACK for us!\n");
1384
1385     /* If just created, cancel the short timeout and start a long one */
1386     if (MESH_CONNECTION_SENT == oldstate)
1387       connection_reset_timeout (c, GNUNET_YES);
1388
1389     /* Change connection and tunnel state */
1390     connection_change_state (c, MESH_CONNECTION_READY);
1391     if (MESH_TUNNEL3_WAITING == GMT_get_state (c->t))
1392       GMT_change_state (c->t, MESH_TUNNEL3_READY);
1393
1394     /* Send ACK (~TCP ACK)*/
1395     send_connection_ack (c, GNUNET_YES);
1396     return GNUNET_OK;
1397   }
1398
1399   /* Message for us as destination? */
1400   if (GMC_is_terminal (c, GNUNET_YES))
1401   {
1402     if (GNUNET_YES != fwd)
1403     {
1404       GNUNET_break_op (0);
1405       return GNUNET_OK;
1406     }
1407     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Connection ACK for us!\n");
1408
1409     /* If just created, cancel the short timeout and start a long one */
1410     if (MESH_CONNECTION_ACK == oldstate)
1411       connection_reset_timeout (c, GNUNET_NO);
1412
1413     /* Change tunnel state */
1414     if (MESH_TUNNEL3_WAITING == GMT_get_state (c->t))
1415       GMT_change_state (c->t, MESH_TUNNEL3_READY);
1416
1417     return GNUNET_OK;
1418   }
1419
1420   LOG (GNUNET_ERROR_TYPE_DEBUG, "  not for us, retransmitting...\n");
1421   GMC_send_prebuilt_message (message, c, fwd, NULL, NULL);
1422   return GNUNET_OK;
1423 }
1424
1425
1426 /**
1427  * Core handler for notifications of broken paths
1428  *
1429  * @param cls Closure (unused).
1430  * @param id Peer identity of sending neighbor.
1431  * @param message Message.
1432  *
1433  * @return GNUNET_OK to keep the connection open,
1434  *         GNUNET_SYSERR to close it (signal serious error)
1435  */
1436 int
1437 GMC_handle_broken (void* cls,
1438                    const struct GNUNET_PeerIdentity* id,
1439                    const struct GNUNET_MessageHeader* message)
1440 {
1441   struct GNUNET_MESH_ConnectionBroken *msg;
1442   struct MeshConnection *c;
1443   int fwd;
1444
1445   LOG (GNUNET_ERROR_TYPE_DEBUG,
1446               "Received a CONNECTION BROKEN msg from %s\n", GNUNET_i2s (id));
1447   msg = (struct GNUNET_MESH_ConnectionBroken *) message;
1448   LOG (GNUNET_ERROR_TYPE_DEBUG, "  regarding %s\n",
1449               GNUNET_i2s (&msg->peer1));
1450   LOG (GNUNET_ERROR_TYPE_DEBUG, "  regarding %s\n",
1451               GNUNET_i2s (&msg->peer2));
1452   c = connection_get (&msg->cid);
1453   if (NULL == c)
1454   {
1455     GNUNET_break_op (0);
1456     return GNUNET_OK;
1457   }
1458
1459   fwd = is_fwd (c, id);
1460   connection_cancel_queues (c, !fwd);
1461   if (GMC_is_terminal (c, fwd))
1462   {
1463     if (0 < c->pending_messages)
1464       c->destroy = GNUNET_YES;
1465     else
1466       GMC_destroy (c);
1467   }
1468   else
1469   {
1470     GMC_send_prebuilt_message (message, c, fwd, NULL, NULL);
1471     c->destroy = GNUNET_YES;
1472   }
1473
1474   return GNUNET_OK;
1475
1476 }
1477
1478
1479 /**
1480  * Core handler for tunnel destruction
1481  *
1482  * @param cls Closure (unused).
1483  * @param peer Peer identity of sending neighbor.
1484  * @param message Message.
1485  *
1486  * @return GNUNET_OK to keep the connection open,
1487  *         GNUNET_SYSERR to close it (signal serious error)
1488  */
1489 int
1490 GMC_handle_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
1491                     const struct GNUNET_MessageHeader *message)
1492 {
1493   struct GNUNET_MESH_ConnectionDestroy *msg;
1494   struct MeshConnection *c;
1495   int fwd;
1496
1497   msg = (struct GNUNET_MESH_ConnectionDestroy *) message;
1498   LOG (GNUNET_ERROR_TYPE_DEBUG,
1499               "Got a CONNECTION DESTROY message from %s\n",
1500               GNUNET_i2s (peer));
1501   LOG (GNUNET_ERROR_TYPE_DEBUG,
1502               "  for connection %s\n",
1503               GNUNET_h2s (&msg->cid));
1504   c = connection_get (&msg->cid);
1505   if (NULL == c)
1506   {
1507     /* Probably already got the message from another path,
1508      * destroyed the tunnel and retransmitted to children.
1509      * Safe to ignore.
1510      */
1511     GNUNET_STATISTICS_update (stats, "# control on unknown tunnel",
1512                               1, GNUNET_NO);
1513     return GNUNET_OK;
1514   }
1515   fwd = is_fwd (c, peer);
1516   if (GNUNET_SYSERR == fwd)
1517   {
1518     GNUNET_break_op (0);
1519     return GNUNET_OK;
1520   }
1521   GMC_send_prebuilt_message (message, c, fwd, NULL, NULL);
1522   c->destroy = GNUNET_YES;
1523
1524   return GNUNET_OK;
1525 }
1526
1527 /**
1528  * Generic handler for mesh network encrypted traffic.
1529  *
1530  * @param peer Peer identity this notification is about.
1531  * @param msg Encrypted message.
1532  *
1533  * @return GNUNET_OK to keep the connection open,
1534  *         GNUNET_SYSERR to close it (signal serious error)
1535  */
1536 static int
1537 handle_mesh_encrypted (const struct GNUNET_PeerIdentity *peer,
1538                        const struct GNUNET_MESH_Encrypted *msg)
1539 {
1540   struct MeshConnection *c;
1541   struct MeshPeer *neighbor;
1542   struct MeshFlowControl *fc;
1543   GNUNET_PEER_Id peer_id;
1544   uint32_t pid;
1545   uint32_t ttl;
1546   uint16_t type;
1547   size_t size;
1548   int fwd;
1549
1550   /* Check size */
1551   size = ntohs (msg->header.size);
1552   if (size <
1553       sizeof (struct GNUNET_MESH_Encrypted) +
1554       sizeof (struct GNUNET_MessageHeader))
1555   {
1556     GNUNET_break_op (0);
1557     return GNUNET_OK;
1558   }
1559   type = ntohs (msg->header.type);
1560   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
1561   LOG (GNUNET_ERROR_TYPE_DEBUG, "got a %s message (#%u) from %s\n",
1562        GNUNET_MESH_DEBUG_M2S (type), ntohl (msg->pid), GNUNET_i2s (peer));
1563
1564   /* Check connection */
1565   c = connection_get (&msg->cid);
1566   if (NULL == c)
1567   {
1568     GNUNET_STATISTICS_update (stats, "# unknown connection", 1, GNUNET_NO);
1569     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING connection unknown\n");
1570     return GNUNET_OK;
1571   }
1572
1573   /* Check if origin is as expected */
1574   neighbor = get_prev_hop (c);
1575   peer_id = GNUNET_PEER_search (peer);
1576   if (peer_id == GMP_get_short_id (neighbor))
1577   {
1578     fwd = GNUNET_YES;
1579   }
1580   else
1581   {
1582     neighbor = get_next_hop (c);
1583     if (peer_id == GMP_get_short_id (neighbor))
1584     {
1585       fwd = GNUNET_NO;
1586     }
1587     else
1588     {
1589       /* Unexpected peer sending traffic on a connection. */
1590       GNUNET_break_op (0);
1591       return GNUNET_OK;
1592     }
1593   }
1594
1595   /* Check PID */
1596   fc = fwd ? &c->bck_fc : &c->fwd_fc;
1597   pid = ntohl (msg->pid);
1598   if (GMC_is_pid_bigger (pid, fc->last_ack_sent))
1599   {
1600     GNUNET_STATISTICS_update (stats, "# unsolicited message", 1, GNUNET_NO);
1601     LOG (GNUNET_ERROR_TYPE_DEBUG,
1602                 "WARNING Received PID %u, (prev %u), ACK %u\n",
1603                 pid, fc->last_pid_recv, fc->last_ack_sent);
1604     return GNUNET_OK;
1605   }
1606   if (GNUNET_NO == GMC_is_pid_bigger (pid, fc->last_pid_recv))
1607   {
1608     GNUNET_STATISTICS_update (stats, "# duplicate PID", 1, GNUNET_NO);
1609     LOG (GNUNET_ERROR_TYPE_DEBUG,
1610                 " Pid %u not expected (%u+), dropping!\n",
1611                 pid, fc->last_pid_recv + 1);
1612     return GNUNET_OK;
1613   }
1614   if (MESH_CONNECTION_SENT == c->state || MESH_CONNECTION_ACK == c->state)
1615     connection_change_state (c, MESH_CONNECTION_READY);
1616   connection_reset_timeout (c, fwd);
1617   fc->last_pid_recv = pid;
1618
1619   /* Is this message for us? */
1620   if (GMC_is_terminal (c, fwd))
1621   {
1622     /* TODO signature verification */
1623     LOG (GNUNET_ERROR_TYPE_DEBUG, "  message for us!\n");
1624     GNUNET_STATISTICS_update (stats, "# messages received", 1, GNUNET_NO);
1625
1626     if (NULL == c->t)
1627     {
1628       GNUNET_break (0);
1629       return GNUNET_OK;
1630     }
1631     fc->last_pid_recv = pid;
1632     GMT_handle_encrypted (c->t, msg);
1633     GMC_send_ack (c, fwd, GNUNET_NO);
1634     return GNUNET_OK;
1635   }
1636
1637   /* Message not for us: forward to next hop */
1638   LOG (GNUNET_ERROR_TYPE_DEBUG, "  not for us, retransmitting...\n");
1639   ttl = ntohl (msg->ttl);
1640   LOG (GNUNET_ERROR_TYPE_DEBUG, "   ttl: %u\n", ttl);
1641   if (ttl == 0)
1642   {
1643     GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
1644     LOG (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
1645     GMC_send_ack (c, fwd, GNUNET_NO);
1646     return GNUNET_OK;
1647   }
1648
1649   GNUNET_STATISTICS_update (stats, "# messages forwarded", 1, GNUNET_NO);
1650   GMC_send_prebuilt_message (&msg->header, c, fwd, NULL, NULL);
1651
1652   return GNUNET_OK;
1653 }
1654
1655 /**
1656  * Generic handler for mesh network encrypted traffic.
1657  *
1658  * @param peer Peer identity this notification is about.
1659  * @param msg Encrypted message.
1660  *
1661  * @return GNUNET_OK to keep the connection open,
1662  *         GNUNET_SYSERR to close it (signal serious error)
1663  */
1664 static int
1665 handle_mesh_kx (const struct GNUNET_PeerIdentity *peer,
1666                 const struct GNUNET_MESH_KX *msg)
1667 {
1668   struct MeshConnection *c;
1669   struct MeshPeer *neighbor;
1670   GNUNET_PEER_Id peer_id;
1671   size_t size;
1672   uint16_t type;
1673   int fwd;
1674
1675   /* Check size */
1676   size = ntohs (msg->header.size);
1677   if (size <
1678       sizeof (struct GNUNET_MESH_Encrypted) +
1679       sizeof (struct GNUNET_MessageHeader))
1680   {
1681     GNUNET_break_op (0);
1682     return GNUNET_OK;
1683   }
1684   type = ntohs (msg->header.type);
1685   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
1686   LOG (GNUNET_ERROR_TYPE_DEBUG, "got a %s message from %s\n",
1687               GNUNET_MESH_DEBUG_M2S (type), GNUNET_i2s (peer));
1688
1689   /* Check connection */
1690   c = connection_get (&msg->cid);
1691   if (NULL == c)
1692   {
1693     GNUNET_STATISTICS_update (stats, "# unknown connection", 1, GNUNET_NO);
1694     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING connection unknown\n");
1695     return GNUNET_OK;
1696   }
1697
1698   /* Check if origin is as expected */
1699   neighbor = get_prev_hop (c);
1700   peer_id = GNUNET_PEER_search (peer);
1701   if (peer_id == GMP_get_short_id (neighbor))
1702   {
1703     fwd = GNUNET_YES;
1704   }
1705   else
1706   {
1707     neighbor = get_next_hop (c);
1708     if (peer_id == GMP_get_short_id (neighbor))
1709     {
1710       fwd = GNUNET_NO;
1711     }
1712     else
1713     {
1714       /* Unexpected peer sending traffic on a connection. */
1715       GNUNET_break_op (0);
1716       return GNUNET_OK;
1717     }
1718   }
1719
1720   /* Count as connection confirmation. */
1721   if (MESH_CONNECTION_SENT == c->state || MESH_CONNECTION_ACK == c->state)
1722     connection_change_state (c, MESH_CONNECTION_READY);
1723   connection_reset_timeout (c, fwd);
1724   if (NULL != c->t)
1725   {
1726     if (MESH_TUNNEL3_WAITING == GMT_get_state (c->t))
1727       GMT_change_state (c->t, MESH_TUNNEL3_READY);
1728   }
1729
1730   /* Is this message for us? */
1731   if (GMC_is_terminal (c, fwd))
1732   {
1733     LOG (GNUNET_ERROR_TYPE_DEBUG, "  message for us!\n");
1734     GNUNET_STATISTICS_update (stats, "# messages received", 1, GNUNET_NO);
1735     if (NULL == c->t)
1736     {
1737       GNUNET_break (0);
1738       return GNUNET_OK;
1739     }
1740     GMT_handle_kx (c->t, &msg[1].header);
1741     return GNUNET_OK;
1742   }
1743
1744   /* Message not for us: forward to next hop */
1745   LOG (GNUNET_ERROR_TYPE_DEBUG, "  not for us, retransmitting...\n");
1746   GNUNET_STATISTICS_update (stats, "# messages forwarded", 1, GNUNET_NO);
1747   GMC_send_prebuilt_message (&msg->header, c, fwd, NULL, NULL);
1748
1749   return GNUNET_OK;
1750 }
1751
1752
1753 /**
1754  * Core handler for encrypted mesh network traffic (channel mgmt, data).
1755  *
1756  * @param cls Closure (unused).
1757  * @param message Message received.
1758  * @param peer Peer who sent the message.
1759  *
1760  * @return GNUNET_OK to keep the connection open,
1761  *         GNUNET_SYSERR to close it (signal serious error)
1762  */
1763 int
1764 GMC_handle_encrypted (void *cls, const struct GNUNET_PeerIdentity *peer,
1765                       const struct GNUNET_MessageHeader *message)
1766 {
1767   return handle_mesh_encrypted (peer,
1768                                 (struct GNUNET_MESH_Encrypted *)message);
1769 }
1770
1771
1772 /**
1773  * Core handler for key exchange traffic (ephemeral key, ping, pong).
1774  *
1775  * @param cls Closure (unused).
1776  * @param message Message received.
1777  * @param peer Peer who sent the message.
1778  *
1779  * @return GNUNET_OK to keep the connection open,
1780  *         GNUNET_SYSERR to close it (signal serious error)
1781  */
1782 int
1783 GMC_handle_kx (void *cls, const struct GNUNET_PeerIdentity *peer,
1784                const struct GNUNET_MessageHeader *message)
1785 {
1786   return handle_mesh_kx (peer,
1787                          (struct GNUNET_MESH_KX *) message);
1788 }
1789
1790
1791 /**
1792  * Core handler for mesh network traffic point-to-point acks.
1793  *
1794  * @param cls closure
1795  * @param message message
1796  * @param peer peer identity this notification is about
1797  *
1798  * @return GNUNET_OK to keep the connection open,
1799  *         GNUNET_SYSERR to close it (signal serious error)
1800  */
1801 int
1802 GMC_handle_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
1803                 const struct GNUNET_MessageHeader *message)
1804 {
1805   struct GNUNET_MESH_ACK *msg;
1806   struct MeshConnection *c;
1807   struct MeshFlowControl *fc;
1808   GNUNET_PEER_Id id;
1809   uint32_t ack;
1810   int fwd;
1811
1812   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
1813   LOG (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK packet from %s!\n",
1814               GNUNET_i2s (peer));
1815   msg = (struct GNUNET_MESH_ACK *) message;
1816
1817   c = connection_get (&msg->cid);
1818
1819   if (NULL == c)
1820   {
1821     GNUNET_STATISTICS_update (stats, "# ack on unknown connection", 1,
1822                               GNUNET_NO);
1823     return GNUNET_OK;
1824   }
1825
1826   /* Is this a forward or backward ACK? */
1827   id = GNUNET_PEER_search (peer);
1828   if (GMP_get_short_id (get_next_hop (c)) == id)
1829   {
1830     LOG (GNUNET_ERROR_TYPE_DEBUG, "  FWD ACK\n");
1831     fc = &c->fwd_fc;
1832     fwd = GNUNET_YES;
1833   }
1834   else if (GMP_get_short_id (get_prev_hop (c)) == id)
1835   {
1836     LOG (GNUNET_ERROR_TYPE_DEBUG, "  BCK ACK\n");
1837     fc = &c->bck_fc;
1838     fwd = GNUNET_NO;
1839   }
1840   else
1841   {
1842     GNUNET_break_op (0);
1843     return GNUNET_OK;
1844   }
1845
1846   ack = ntohl (msg->ack);
1847   LOG (GNUNET_ERROR_TYPE_DEBUG, "  ACK %u (was %u)\n",
1848               ack, fc->last_ack_recv);
1849   if (GMC_is_pid_bigger (ack, fc->last_ack_recv))
1850     fc->last_ack_recv = ack;
1851
1852   /* Cancel polling if the ACK is big enough. */
1853   if (GNUNET_SCHEDULER_NO_TASK != fc->poll_task &&
1854       GMC_is_pid_bigger (fc->last_ack_recv, fc->last_pid_sent))
1855   {
1856     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Cancel poll\n");
1857     GNUNET_SCHEDULER_cancel (fc->poll_task);
1858     fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
1859     fc->poll_time = GNUNET_TIME_UNIT_SECONDS;
1860   }
1861
1862   connection_unlock_queue (c, fwd);
1863
1864   return GNUNET_OK;
1865 }
1866
1867
1868 /**
1869  * Core handler for mesh network traffic point-to-point ack polls.
1870  *
1871  * @param cls closure
1872  * @param message message
1873  * @param peer peer identity this notification is about
1874  *
1875  * @return GNUNET_OK to keep the connection open,
1876  *         GNUNET_SYSERR to close it (signal serious error)
1877  */
1878 int
1879 GMC_handle_poll (void *cls, const struct GNUNET_PeerIdentity *peer,
1880                  const struct GNUNET_MessageHeader *message)
1881 {
1882   struct GNUNET_MESH_Poll *msg;
1883   struct MeshConnection *c;
1884   struct MeshFlowControl *fc;
1885   GNUNET_PEER_Id id;
1886   uint32_t pid;
1887   int fwd;
1888
1889   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
1890   LOG (GNUNET_ERROR_TYPE_DEBUG,
1891        "Got a POLL packet from %s!\n",
1892        GNUNET_i2s (peer));
1893
1894   msg = (struct GNUNET_MESH_Poll *) message;
1895
1896   c = connection_get (&msg->cid);
1897
1898   if (NULL == c)
1899   {
1900     GNUNET_STATISTICS_update (stats, "# poll on unknown connection", 1,
1901                               GNUNET_NO);
1902     GNUNET_break_op (0);
1903     return GNUNET_OK;
1904   }
1905
1906   /* Is this a forward or backward ACK?
1907    * Note: a poll should never be needed in a loopback case,
1908    * since there is no possiblility of packet loss there, so
1909    * this way of discerining FWD/BCK should not be a problem.
1910    */
1911   id = GNUNET_PEER_search (peer);
1912   if (GMP_get_short_id (get_next_hop (c)) == id)
1913   {
1914     LOG (GNUNET_ERROR_TYPE_DEBUG, "  FWD FC\n");
1915     fc = &c->fwd_fc;
1916   }
1917   else if (GMP_get_short_id (get_prev_hop (c)) == id)
1918   {
1919     LOG (GNUNET_ERROR_TYPE_DEBUG, "  BCK FC\n");
1920     fc = &c->bck_fc;
1921   }
1922   else
1923   {
1924     GNUNET_break_op (0);
1925     return GNUNET_OK;
1926   }
1927
1928   pid = ntohl (msg->pid);
1929   LOG (GNUNET_ERROR_TYPE_DEBUG, "  PID %u, OLD %u\n", pid, fc->last_pid_recv);
1930   fc->last_pid_recv = pid;
1931   fwd = fc == &c->bck_fc;
1932   GMC_send_ack (c, fwd, GNUNET_YES);
1933
1934   return GNUNET_OK;
1935 }
1936
1937
1938 /**
1939  * Core handler for mesh keepalives.
1940  *
1941  * @param cls closure
1942  * @param message message
1943  * @param peer peer identity this notification is about
1944  * @return GNUNET_OK to keep the connection open,
1945  *         GNUNET_SYSERR to close it (signal serious error)
1946  *
1947  * TODO: Check who we got this from, to validate route.
1948  */
1949 int
1950 GMC_handle_keepalive (void *cls, const struct GNUNET_PeerIdentity *peer,
1951                       const struct GNUNET_MessageHeader *message)
1952 {
1953   struct GNUNET_MESH_ConnectionKeepAlive *msg;
1954   struct MeshConnection *c;
1955   struct MeshPeer *neighbor;
1956   int fwd;
1957
1958   msg = (struct GNUNET_MESH_ConnectionKeepAlive *) message;
1959   LOG (GNUNET_ERROR_TYPE_DEBUG, "got a keepalive packet from %s\n",
1960               GNUNET_i2s (peer));
1961
1962   c = connection_get (&msg->cid);
1963   if (NULL == c)
1964   {
1965     GNUNET_STATISTICS_update (stats, "# keepalive on unknown connection", 1,
1966                               GNUNET_NO);
1967     return GNUNET_OK;
1968   }
1969
1970   fwd = GNUNET_MESSAGE_TYPE_MESH_FWD_KEEPALIVE == ntohs (message->type) ?
1971         GNUNET_YES : GNUNET_NO;
1972
1973   /* Check if origin is as expected */
1974   neighbor = get_hop (c, fwd);
1975   if (GNUNET_PEER_search (peer) != GMP_get_short_id (neighbor))
1976   {
1977     GNUNET_break_op (0);
1978     return GNUNET_OK;
1979   }
1980
1981   connection_change_state (c, MESH_CONNECTION_READY);
1982   connection_reset_timeout (c, fwd);
1983
1984   if (GMC_is_terminal (c, fwd))
1985     return GNUNET_OK;
1986
1987   GNUNET_STATISTICS_update (stats, "# keepalives forwarded", 1, GNUNET_NO);
1988   GMC_send_prebuilt_message (message, c, fwd, NULL, NULL);
1989
1990   return GNUNET_OK;
1991 }
1992
1993
1994 /**
1995  * Send an ACK on the appropriate connection/channel, depending on
1996  * the direction and the position of the peer.
1997  *
1998  * @param c Which connection to send the hop-by-hop ACK.
1999  * @param fwd Is this a fwd ACK? (will go dest->root).
2000  * @param force Send the ACK even if suboptimal (e.g. requested by POLL).
2001  */
2002 void
2003 GMC_send_ack (struct MeshConnection *c, int fwd, int force)
2004 {
2005   unsigned int buffer;
2006
2007   LOG (GNUNET_ERROR_TYPE_DEBUG,
2008        "GMC send %s ACK on %s\n",
2009        fwd ? "FWD" : "BCK", GMC_2s (c));
2010
2011   if (NULL == c)
2012   {
2013     GNUNET_break (0);
2014     return;
2015   }
2016
2017   /* Get available buffer space */
2018   if (GMC_is_terminal (c, fwd))
2019   {
2020     LOG (GNUNET_ERROR_TYPE_DEBUG, "  getting from all channels\n");
2021     buffer = GMT_get_channels_buffer (c->t);
2022   }
2023   else
2024   {
2025     LOG (GNUNET_ERROR_TYPE_DEBUG, "  getting from one connection\n");
2026     buffer = GMC_get_buffer (c, fwd);
2027   }
2028   LOG (GNUNET_ERROR_TYPE_DEBUG, "  buffer available: %u\n", buffer);
2029   if (0 == buffer && GNUNET_NO == force)
2030     return;
2031
2032   /* Send available buffer space */
2033   if (GMC_is_origin (c, fwd))
2034   {
2035     GNUNET_assert (NULL != c->t);
2036     LOG (GNUNET_ERROR_TYPE_DEBUG, "  sending on channels...\n");
2037     GMT_unchoke_channels (c->t);
2038   }
2039   else
2040   {
2041     LOG (GNUNET_ERROR_TYPE_DEBUG, "  sending on connection\n");
2042     send_ack (c, buffer, fwd, force);
2043   }
2044 }
2045
2046
2047 /**
2048  * Initialize the connections subsystem
2049  *
2050  * @param c Configuration handle.
2051  */
2052 void
2053 GMC_init (const struct GNUNET_CONFIGURATION_Handle *c)
2054 {
2055   LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
2056   if (GNUNET_OK !=
2057       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_MSGS_QUEUE",
2058                                              &max_msgs_queue))
2059   {
2060     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
2061                                "MESH", "MAX_MSGS_QUEUE", "MISSING");
2062     GNUNET_SCHEDULER_shutdown ();
2063     return;
2064   }
2065
2066   if (GNUNET_OK !=
2067       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_CONNECTIONS",
2068                                              &max_connections))
2069   {
2070     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
2071                                "MESH", "MAX_CONNECTIONS", "MISSING");
2072     GNUNET_SCHEDULER_shutdown ();
2073     return;
2074   }
2075
2076   if (GNUNET_OK !=
2077       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "REFRESH_CONNECTION_TIME",
2078                                            &refresh_connection_time))
2079   {
2080     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
2081                                "MESH", "REFRESH_CONNECTION_TIME", "MISSING");
2082     GNUNET_SCHEDULER_shutdown ();
2083     return;
2084   }
2085   create_connection_time = GNUNET_TIME_UNIT_SECONDS;
2086   connections = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_YES);
2087 }
2088
2089
2090 /**
2091  * Destroy each connection on shutdown.
2092  *
2093  * @param cls Closure (unused).
2094  * @param key Current key code (CID, unused).
2095  * @param value Value in the hash map (connection)
2096  *
2097  * @return #GNUNET_YES, because we should continue to iterate,
2098  */
2099 static int
2100 shutdown_iterator (void *cls,
2101                    const struct GNUNET_HashCode *key,
2102                    void *value)
2103 {
2104   struct MeshConnection *c = value;
2105
2106   GMC_destroy (c);
2107   return GNUNET_YES;
2108 }
2109
2110
2111 /**
2112  * Shut down the connections subsystem.
2113  */
2114 void
2115 GMC_shutdown (void)
2116 {
2117   GNUNET_CONTAINER_multihashmap_iterate (connections, &shutdown_iterator, NULL);
2118   GNUNET_CONTAINER_multihashmap_destroy (connections);
2119   connections = NULL;
2120 }
2121
2122
2123 struct MeshConnection *
2124 GMC_new (const struct GNUNET_HashCode *cid,
2125          struct MeshTunnel3 *t,
2126          struct MeshPeerPath *p,
2127          unsigned int own_pos)
2128 {
2129   struct MeshConnection *c;
2130
2131   c = GNUNET_new (struct MeshConnection);
2132   c->id = *cid;
2133   GNUNET_CONTAINER_multihashmap_put (connections, &c->id, c,
2134                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
2135   fc_init (&c->fwd_fc);
2136   fc_init (&c->bck_fc);
2137   c->fwd_fc.c = c;
2138   c->bck_fc.c = c;
2139
2140   c->t = t;
2141   if (own_pos > p->length - 1)
2142   {
2143     GNUNET_break (0);
2144     GMC_destroy (c);
2145     return NULL;
2146   }
2147   c->own_pos = own_pos;
2148   c->path = p;
2149
2150   if (0 == own_pos)
2151   {
2152     c->fwd_maintenance_task =
2153             GNUNET_SCHEDULER_add_delayed (create_connection_time,
2154                                           &connection_fwd_keepalive, c);
2155   }
2156   if (GNUNET_OK != register_neighbors (c))
2157   {
2158     GMC_destroy (c);
2159     return NULL;
2160   }
2161
2162   return c;
2163 }
2164
2165
2166 void
2167 GMC_destroy (struct MeshConnection *c)
2168 {
2169   if (NULL == c)
2170     return;
2171
2172   if (2 == c->destroy) /* cancel queues -> GMP_queue_cancel -> q_destroy -> */
2173     return;            /* -> message_sent -> GMC_destroy. Don't loop. */
2174   c->destroy = 2;
2175
2176   LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying connection %s\n", GMC_2s (c));
2177   LOG (GNUNET_ERROR_TYPE_DEBUG, " fc's f: %p, b: %p\n",
2178        &c->fwd_fc, &c->bck_fc);
2179   LOG (GNUNET_ERROR_TYPE_DEBUG, " fc tasks f: %u, b: %u\n",
2180        c->fwd_fc.poll_task, c->bck_fc.poll_task);
2181
2182   /* Cancel all traffic */
2183   connection_cancel_queues (c, GNUNET_YES);
2184   connection_cancel_queues (c, GNUNET_NO);
2185
2186   LOG (GNUNET_ERROR_TYPE_DEBUG, " fc tasks f: %u, b: %u\n",
2187        c->fwd_fc.poll_task, c->bck_fc.poll_task);
2188
2189   /* Cancel maintainance task (keepalive/timeout) */
2190   if (GNUNET_SCHEDULER_NO_TASK != c->fwd_maintenance_task)
2191     GNUNET_SCHEDULER_cancel (c->fwd_maintenance_task);
2192   if (GNUNET_SCHEDULER_NO_TASK != c->bck_maintenance_task)
2193     GNUNET_SCHEDULER_cancel (c->bck_maintenance_task);
2194   if (GNUNET_SCHEDULER_NO_TASK != c->fwd_fc.poll_task)
2195   {
2196     GNUNET_SCHEDULER_cancel (c->fwd_fc.poll_task);
2197     LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL FWD canceled\n");
2198   }
2199   if (GNUNET_SCHEDULER_NO_TASK != c->bck_fc.poll_task)
2200   {
2201     GNUNET_SCHEDULER_cancel (c->bck_fc.poll_task);
2202     LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL BCK canceled\n");
2203   }
2204   if (NULL != c->fwd_fc.poll_msg)
2205   {
2206     GMC_cancel (c->fwd_fc.poll_msg);
2207     LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL msg FWD canceled\n");
2208   }
2209   if (NULL != c->bck_fc.poll_msg)
2210   {
2211     GMC_cancel (c->bck_fc.poll_msg);
2212     LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL msg BCK canceled\n");
2213   }
2214
2215   /* Unregister from neighbors */
2216   unregister_neighbors (c);
2217
2218   /* Delete */
2219   GNUNET_STATISTICS_update (stats, "# connections", -1, GNUNET_NO);
2220   if (NULL != c->t)
2221     GMT_remove_connection (c->t, c);
2222
2223   if (GNUNET_NO == GMC_is_origin (c, GNUNET_YES))
2224     path_destroy (c->path);
2225
2226   GNUNET_break (GNUNET_YES ==
2227                 GNUNET_CONTAINER_multihashmap_remove (connections, &c->id, c));
2228
2229   GNUNET_free (c);
2230 }
2231
2232 /**
2233  * Get the connection ID.
2234  *
2235  * @param c Connection to get the ID from.
2236  *
2237  * @return ID of the connection.
2238  */
2239 const struct GNUNET_HashCode *
2240 GMC_get_id (const struct MeshConnection *c)
2241 {
2242   return &c->id;
2243 }
2244
2245
2246 /**
2247  * Get the connection path.
2248  *
2249  * @param c Connection to get the path from.
2250  *
2251  * @return path used by the connection.
2252  */
2253 const struct MeshPeerPath *
2254 GMC_get_path (const struct MeshConnection *c)
2255 {
2256   return c->path;
2257 }
2258
2259
2260 /**
2261  * Get the connection state.
2262  *
2263  * @param c Connection to get the state from.
2264  *
2265  * @return state of the connection.
2266  */
2267 enum MeshConnectionState
2268 GMC_get_state (const struct MeshConnection *c)
2269 {
2270   return c->state;
2271 }
2272
2273 /**
2274  * Get the connection tunnel.
2275  *
2276  * @param c Connection to get the tunnel from.
2277  *
2278  * @return tunnel of the connection.
2279  */
2280 struct MeshTunnel3 *
2281 GMC_get_tunnel (const struct MeshConnection *c)
2282 {
2283   return c->t;
2284 }
2285
2286
2287 /**
2288  * Get free buffer space in a connection.
2289  *
2290  * @param c Connection.
2291  * @param fwd Is query about FWD traffic?
2292  *
2293  * @return Free buffer space [0 - max_msgs_queue/max_connections]
2294  */
2295 unsigned int
2296 GMC_get_buffer (struct MeshConnection *c, int fwd)
2297 {
2298   struct MeshFlowControl *fc;
2299
2300   fc = fwd ? &c->fwd_fc : &c->bck_fc;
2301
2302   return (fc->queue_max - fc->queue_n);
2303 }
2304
2305 /**
2306  * Get how many messages have we allowed to send to us from a direction.
2307  *
2308  * @param c Connection.
2309  * @param fwd Are we asking about traffic from FWD (BCK messages)?
2310  *
2311  * @return last_ack_sent - last_pid_recv
2312  */
2313 unsigned int
2314 GMC_get_allowed (struct MeshConnection *c, int fwd)
2315 {
2316   struct MeshFlowControl *fc;
2317
2318   fc = fwd ? &c->fwd_fc : &c->bck_fc;
2319   if (GMC_is_pid_bigger(fc->last_pid_recv, fc->last_ack_sent))
2320   {
2321     return 0;
2322   }
2323   return (fc->last_ack_sent - fc->last_pid_recv);
2324 }
2325
2326 /**
2327  * Get messages queued in a connection.
2328  *
2329  * @param c Connection.
2330  * @param fwd Is query about FWD traffic?
2331  *
2332  * @return Number of messages queued.
2333  */
2334 unsigned int
2335 GMC_get_qn (struct MeshConnection *c, int fwd)
2336 {
2337   struct MeshFlowControl *fc;
2338
2339   fc = fwd ? &c->fwd_fc : &c->bck_fc;
2340
2341   return fc->queue_n;
2342 }
2343
2344
2345 /**
2346  * Allow the connection to advertise a buffer of the given size.
2347  *
2348  * The connection will send an @c fwd ACK message (so: in direction !fwd)
2349  * allowing up to last_pid_recv + buffer.
2350  *
2351  * @param c Connection.
2352  * @param buffer How many more messages the connection can accept.
2353  * @param fwd Is this about FWD traffic? (The ack will go dest->root).
2354  */
2355 void
2356 GMC_allow (struct MeshConnection *c, unsigned int buffer, int fwd)
2357 {
2358   send_ack (c, buffer, fwd, GNUNET_NO);
2359 }
2360
2361
2362 /**
2363  * Notify other peers on a connection of a broken link. Mark connections
2364  * to destroy after all traffic has been sent.
2365  *
2366  * @param c Connection on which there has been a disconnection.
2367  * @param peer Peer that disconnected.
2368  */
2369 void
2370 GMC_notify_broken (struct MeshConnection *c,
2371                    struct MeshPeer *peer)
2372 {
2373   int fwd;
2374
2375   LOG (GNUNET_ERROR_TYPE_DEBUG,
2376        " notify broken on %s due to %s disconnect\n",
2377        GMC_2s (c), GMP_2s (peer));
2378
2379   fwd = peer == get_prev_hop (c);
2380
2381   if (GNUNET_YES == GMC_is_terminal (c, fwd))
2382   {
2383     /* Local shutdown, no one to notify about this. */
2384     GMC_destroy (c);
2385     return;
2386   }
2387   if (GNUNET_NO == c->destroy)
2388     send_broken (c, &my_full_id, GMP_get_id (peer), fwd);
2389
2390   /* Connection will have at least one pending message
2391    * (the one we just scheduled), so no point in checking whether to
2392    * destroy immediately. */
2393   c->destroy = GNUNET_YES;
2394
2395   /**
2396    * Cancel all queues, if no message is left, connection will be destroyed.
2397    */
2398   connection_cancel_queues (c, !fwd);
2399
2400   return;
2401 }
2402
2403
2404 /**
2405  * Is this peer the first one on the connection?
2406  *
2407  * @param c Connection.
2408  * @param fwd Is this about fwd traffic?
2409  *
2410  * @return #GNUNET_YES if origin, #GNUNET_NO if relay/terminal.
2411  */
2412 int
2413 GMC_is_origin (struct MeshConnection *c, int fwd)
2414 {
2415   if (!fwd && c->path->length - 1 == c->own_pos )
2416     return GNUNET_YES;
2417   if (fwd && 0 == c->own_pos)
2418     return GNUNET_YES;
2419   return GNUNET_NO;
2420 }
2421
2422
2423 /**
2424  * Is this peer the last one on the connection?
2425  *
2426  * @param c Connection.
2427  * @param fwd Is this about fwd traffic?
2428  *            Note that the ROOT is the terminal for BCK traffic!
2429  *
2430  * @return #GNUNET_YES if terminal, #GNUNET_NO if relay/origin.
2431  */
2432 int
2433 GMC_is_terminal (struct MeshConnection *c, int fwd)
2434 {
2435   return GMC_is_origin (c, !fwd);
2436 }
2437
2438
2439 /**
2440  * See if we are allowed to send by the next hop in the given direction.
2441  *
2442  * @param c Connection.
2443  * @param fwd Is this about fwd traffic?
2444  *
2445  * @return #GNUNET_YES in case it's OK to send.
2446  */
2447 int
2448 GMC_is_sendable (struct MeshConnection *c, int fwd)
2449 {
2450   struct MeshFlowControl *fc;
2451
2452   fc = fwd ? &c->fwd_fc : &c->bck_fc;
2453   if (GMC_is_pid_bigger (fc->last_ack_recv, fc->last_pid_sent))
2454     return GNUNET_YES;
2455   return GNUNET_NO;
2456 }
2457
2458 /**
2459  * Sends an already built message on a connection, properly registering
2460  * all used resources.
2461  *
2462  * @param message Message to send. Function makes a copy of it.
2463  *                If message is not hop-by-hop, decrements TTL of copy.
2464  * @param c Connection on which this message is transmitted.
2465  * @param fwd Is this a fwd message?
2466  * @param cont Continuation called once message is sent. Can be NULL.
2467  * @param cont_cls Closure for @c cont.
2468  *
2469  * @return Handle to cancel the message before it's sent.
2470  *         NULL on error or if @c cont is NULL.
2471  *         Invalid on @c cont call.
2472  */
2473 struct MeshConnectionQueue *
2474 GMC_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
2475                            struct MeshConnection *c, int fwd,
2476                            GMC_sent cont, void *cont_cls)
2477 {
2478   struct MeshFlowControl *fc;
2479   struct MeshConnectionQueue *q;
2480   void *data;
2481   size_t size;
2482   uint16_t type;
2483   int droppable;
2484
2485   size = ntohs (message->size);
2486   data = GNUNET_malloc (size);
2487   memcpy (data, message, size);
2488   type = ntohs (message->type);
2489   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send %s (%u bytes) on connection %s\n",
2490               GNUNET_MESH_DEBUG_M2S (type), size, GMC_2s (c));
2491
2492   fc = fwd ? &c->fwd_fc : &c->bck_fc;
2493   droppable = GNUNET_YES;
2494   switch (type)
2495   {
2496     struct GNUNET_MESH_Encrypted *emsg;
2497     struct GNUNET_MESH_KX        *kmsg;
2498     struct GNUNET_MESH_ACK       *amsg;
2499     struct GNUNET_MESH_Poll      *pmsg;
2500     struct GNUNET_MESH_ConnectionDestroy *dmsg;
2501     struct GNUNET_MESH_ConnectionBroken  *bmsg;
2502     uint32_t ttl;
2503
2504     case GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED:
2505       emsg = (struct GNUNET_MESH_Encrypted *) data;
2506       ttl = ntohl (emsg->ttl);
2507       if (0 == ttl)
2508       {
2509         GNUNET_break_op (0);
2510         GNUNET_free (data);
2511         return NULL;
2512       }
2513       emsg->cid = c->id;
2514       emsg->ttl = htonl (ttl - 1);
2515       emsg->pid = htonl (fc->next_pid++);
2516       LOG (GNUNET_ERROR_TYPE_DEBUG, "  Q_N+ %p %u\n", fc, fc->queue_n);
2517       fc->queue_n++;
2518       LOG (GNUNET_ERROR_TYPE_DEBUG, "pid %u\n", ntohl (emsg->pid));
2519       LOG (GNUNET_ERROR_TYPE_DEBUG, "last pid sent %u\n", fc->last_pid_sent);
2520       LOG (GNUNET_ERROR_TYPE_DEBUG, "     ack recv %u\n", fc->last_ack_recv);
2521       if (GMC_is_pid_bigger (fc->last_pid_sent + 1, fc->last_ack_recv))
2522       {
2523         GMC_start_poll (c, fwd);
2524       }
2525       break;
2526
2527     case GNUNET_MESSAGE_TYPE_MESH_KX:
2528       kmsg = (struct GNUNET_MESH_KX *) data;
2529       kmsg->cid = c->id;
2530       break;
2531
2532     case GNUNET_MESSAGE_TYPE_MESH_ACK:
2533       amsg = (struct GNUNET_MESH_ACK *) data;
2534       amsg->cid = c->id;
2535       LOG (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ntohl (amsg->ack));
2536       droppable = GNUNET_NO;
2537       break;
2538
2539     case GNUNET_MESSAGE_TYPE_MESH_POLL:
2540       pmsg = (struct GNUNET_MESH_Poll *) data;
2541       pmsg->cid = c->id;
2542       LOG (GNUNET_ERROR_TYPE_DEBUG, " poll %u\n", ntohl (pmsg->pid));
2543       droppable = GNUNET_NO;
2544       break;
2545
2546     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_DESTROY:
2547       dmsg = (struct GNUNET_MESH_ConnectionDestroy *) data;
2548       dmsg->cid = c->id;
2549       dmsg->reserved = 0;
2550       break;
2551
2552     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN:
2553       bmsg = (struct GNUNET_MESH_ConnectionBroken *) data;
2554       bmsg->cid = c->id;
2555       bmsg->reserved = 0;
2556       break;
2557
2558     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE:
2559     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK:
2560       break;
2561
2562     default:
2563       GNUNET_break (0);
2564   }
2565
2566   if (fc->queue_n > fc->queue_max && droppable)
2567   {
2568     GNUNET_STATISTICS_update (stats, "# messages dropped (buffer full)",
2569                               1, GNUNET_NO);
2570     GNUNET_break (0);
2571     LOG (GNUNET_ERROR_TYPE_DEBUG,
2572                 "queue full: %u/%u\n",
2573                 fc->queue_n, fc->queue_max);
2574     if (GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED == type)
2575     {
2576       fc->queue_n--;
2577       fc->next_pid--;
2578     }
2579     GNUNET_free (data);
2580     return NULL; /* Drop this message */
2581   }
2582
2583   LOG (GNUNET_ERROR_TYPE_DEBUG, "  C_P+ %p %u\n", c, c->pending_messages);
2584   c->pending_messages++;
2585
2586   if (NULL == cont)
2587   {
2588     (void) GMP_queue_add (get_hop (c, fwd), data, type, size, c, fwd,
2589                           &message_sent, NULL);
2590     return NULL;
2591   }
2592
2593   q = GNUNET_new (struct MeshConnectionQueue);
2594   q->q = GMP_queue_add (get_hop (c, fwd), data, type, size, c, fwd,
2595                         &message_sent, q);
2596   if (NULL == q->q)
2597   {
2598     GNUNET_break (0);
2599     GNUNET_free (data);
2600     GNUNET_free (q);
2601     return NULL;
2602   }
2603   q->cont = cont;
2604   q->cont_cls = cont_cls;
2605   return q;
2606 }
2607
2608
2609 /**
2610  * Cancel a previously sent message while it's in the queue.
2611  *
2612  * ONLY can be called before the continuation given to the send function
2613  * is called. Once the continuation is called, the message is no longer in the
2614  * queue.
2615  *
2616  * @param q Handle to the queue.
2617  */
2618 void
2619 GMC_cancel (struct MeshConnectionQueue *q)
2620 {
2621   LOG (GNUNET_ERROR_TYPE_DEBUG, "!  GMC cancel message\n");
2622
2623   /* queue destroy calls message_sent, which calls q->cont and frees q */
2624   GMP_queue_destroy (q->q, GNUNET_YES);
2625 }
2626
2627
2628 /**
2629  * Sends a CREATE CONNECTION message for a path to a peer.
2630  * Changes the connection and tunnel states if necessary.
2631  *
2632  * @param connection Connection to create.
2633  */
2634 void
2635 GMC_send_create (struct MeshConnection *connection)
2636 {
2637   enum MeshTunnel3State state;
2638   size_t size;
2639
2640   size = sizeof (struct GNUNET_MESH_ConnectionCreate);
2641   size += connection->path->length * sizeof (struct GNUNET_PeerIdentity);
2642   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send connection create\n");
2643   GMP_queue_add (get_next_hop (connection), NULL,
2644                  GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE,
2645                  size, connection, GNUNET_YES, &message_sent, NULL);
2646   LOG (GNUNET_ERROR_TYPE_DEBUG, "  C_P+ %p %u (create)\n",
2647        connection, connection->pending_messages);
2648   connection->pending_messages++;
2649   state = GMT_get_state (connection->t);
2650   if (MESH_TUNNEL3_SEARCHING == state || MESH_TUNNEL3_NEW == state)
2651     GMT_change_state (connection->t, MESH_TUNNEL3_WAITING);
2652   if (MESH_CONNECTION_NEW == connection->state)
2653     connection_change_state (connection, MESH_CONNECTION_SENT);
2654 }
2655
2656
2657 /**
2658  * Send a message to all peers in this connection that the connection
2659  * is no longer valid.
2660  *
2661  * If some peer should not receive the message, it should be zero'ed out
2662  * before calling this function.
2663  *
2664  * @param c The connection whose peers to notify.
2665  */
2666 void
2667 GMC_send_destroy (struct MeshConnection *c)
2668 {
2669   struct GNUNET_MESH_ConnectionDestroy msg;
2670
2671   if (GNUNET_YES == c->destroy)
2672     return;
2673
2674   msg.header.size = htons (sizeof (msg));
2675   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_DESTROY);;
2676   msg.cid = c->id;
2677   LOG (GNUNET_ERROR_TYPE_DEBUG,
2678               "  sending connection destroy for connection %s\n",
2679               GMC_2s (c));
2680
2681   if (GNUNET_NO == GMC_is_terminal (c, GNUNET_YES))
2682     GMC_send_prebuilt_message (&msg.header, c, GNUNET_YES, NULL, NULL);
2683   if (GNUNET_NO == GMC_is_terminal (c, GNUNET_NO))
2684     GMC_send_prebuilt_message (&msg.header, c, GNUNET_NO, NULL, NULL);
2685   c->destroy = GNUNET_YES;
2686 }
2687
2688
2689 /**
2690  * @brief Start a polling timer for the connection.
2691  *
2692  * When a neighbor does not accept more traffic on the connection it could be
2693  * caused by a simple congestion or by a lost ACK. Polling enables to check
2694  * for the lastest ACK status for a connection.
2695  *
2696  * @param c Connection.
2697  * @param fwd Should we poll in the FWD direction?
2698  */
2699 void
2700 GMC_start_poll (struct MeshConnection *c, int fwd)
2701 {
2702   struct MeshFlowControl *fc;
2703
2704   fc = fwd ? &c->fwd_fc : &c->bck_fc;
2705   LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL %s requested\n",
2706        fwd ? "FWD" : "BCK");
2707   if (GNUNET_SCHEDULER_NO_TASK != fc->poll_task && NULL != fc->poll_msg)
2708   {
2709     LOG (GNUNET_ERROR_TYPE_DEBUG, " ***   not needed (%u, %p)\n",
2710          fc->poll_task, fc->poll_msg);
2711     return;
2712   }
2713   LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL started on request\n");
2714   fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
2715                                                 &connection_poll,
2716                                                 fc);
2717 }
2718
2719
2720 /**
2721  * @brief Stop polling a connection for ACKs.
2722  *
2723  * Once we have enough ACKs for future traffic, polls are no longer necessary.
2724  *
2725  * @param c Connection.
2726  * @param fwd Should we stop the poll in the FWD direction?
2727  */
2728 void
2729 GMC_stop_poll (struct MeshConnection *c, int fwd)
2730 {
2731   struct MeshFlowControl *fc;
2732
2733   fc = fwd ? &c->fwd_fc : &c->bck_fc;
2734   if (GNUNET_SCHEDULER_NO_TASK != fc->poll_task)
2735   {
2736     GNUNET_SCHEDULER_cancel (fc->poll_task);
2737     fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
2738   }
2739 }
2740
2741 /**
2742  * Get a (static) string for a connection.
2743  *
2744  * @param c Connection.
2745  */
2746 const char *
2747 GMC_2s (struct MeshConnection *c)
2748 {
2749   if (NULL != c->t)
2750   {
2751     static char buf[128];
2752
2753     sprintf (buf, "%s (->%s)", GNUNET_h2s (&c->id), GMT_2s (c->t));
2754     return buf;
2755   }
2756   return GNUNET_h2s (&c->id);
2757 }