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