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