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