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