- remove MESH own block code (MESH uses DHT_HELLO now)
[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_INFO, "Send %s ACK on connection %s\n",
788        GM_f2s (!fwd), GMC_2s (connection));
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   LOG (GNUNET_ERROR_TYPE_INFO,
845        "Send BROKEN on unknown connection %s\n", GNUNET_h2s (connection_id));
846
847   msg = GNUNET_new (struct GNUNET_MESH_ConnectionBroken);
848   msg->header.size = htons (sizeof (struct GNUNET_MESH_ConnectionBroken));
849   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN);
850   msg->cid = *connection_id;
851   msg->peer1 = *id1;
852   msg->peer2 = *id2;
853   neighbor = GMP_get_short (peer_id);
854   GMP_queue_add (neighbor, msg,
855                  GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED,
856                  sizeof (struct GNUNET_MESH_ConnectionBroken),
857                  NULL, GNUNET_SYSERR, /* connection, fwd */
858                  NULL, NULL); /* continuation */
859 }
860
861
862 /**
863  * Send keepalive packets for a connection.
864  *
865  * @param c Connection to keep alive..
866  * @param fwd Is this a FWD keepalive? (owner -> dest).
867  */
868 static void
869 connection_keepalive (struct MeshConnection *c, int fwd)
870 {
871   struct GNUNET_MESH_ConnectionKeepAlive *msg;
872   size_t size = sizeof (struct GNUNET_MESH_ConnectionKeepAlive);
873   char cbuf[size];
874
875   LOG (GNUNET_ERROR_TYPE_DEBUG,
876        "sending %s keepalive for connection %s]\n",
877        GM_f2s (fwd), GMC_2s (c));
878
879   msg = (struct GNUNET_MESH_ConnectionKeepAlive *) cbuf;
880   msg->header.size = htons (size);
881   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_KEEPALIVE);
882   msg->cid = c->id;
883   msg->reserved = htonl (0);
884
885   GMC_send_prebuilt_message (&msg->header, c, fwd, GNUNET_YES, NULL, NULL);
886 }
887
888
889 /**
890  * Send CONNECTION_{CREATE/ACK} packets for a connection.
891  *
892  * @param c Connection for which to send the message.
893  * @param fwd If #GNUNET_YES, send CREATE, otherwise send ACK.
894  */
895 static void
896 connection_recreate (struct MeshConnection *c, int fwd)
897 {
898   LOG (GNUNET_ERROR_TYPE_DEBUG, "sending connection recreate\n");
899   if (fwd)
900     GMC_send_create (c);
901   else
902     send_connection_ack (c, GNUNET_NO);
903 }
904
905
906 /**
907  * Generic connection timer management.
908  * Depending on the role of the peer in the connection will send the
909  * appropriate message (build or keepalive)
910  *
911  * @param c Conncetion to maintain.
912  * @param fwd Is FWD?
913  */
914 static void
915 connection_maintain (struct MeshConnection *c, int fwd)
916 {
917   if (GNUNET_NO != c->destroy)
918     return;
919
920   if (MESH_TUNNEL3_SEARCHING == GMT_get_cstate (c->t))
921   {
922     /* TODO DHT GET with RO_BART */
923     return;
924   }
925   switch (c->state)
926   {
927     case MESH_CONNECTION_NEW:
928       GNUNET_break (0);
929       /* fall-through */
930     case MESH_CONNECTION_SENT:
931       connection_recreate (c, fwd);
932       break;
933     case MESH_CONNECTION_READY:
934       connection_keepalive (c, fwd);
935       break;
936     default:
937       break;
938   }
939 }
940
941
942 /**
943  * Keep the connection alive in the FWD direction.
944  *
945  * @param cls Closure (connection to keepalive).
946  * @param tc TaskContext.
947  */
948 static void
949 connection_fwd_keepalive (void *cls,
950                           const struct GNUNET_SCHEDULER_TaskContext *tc)
951 {
952   struct MeshConnection *c = cls;
953
954   LOG (GNUNET_ERROR_TYPE_DEBUG, "FWD keepalive for %s\n", GMC_2s (c));
955   c->fwd_maintenance_task = GNUNET_SCHEDULER_NO_TASK;
956   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
957     return;
958
959   connection_maintain (c, GNUNET_YES);
960
961   /* Next execution will be scheduled by message_sent */
962 }
963
964
965 /**
966  * Keep the connection alive in the BCK direction.
967  *
968  * TODO refactor and merge with connection_fwd_keepalive.
969  *
970  * @param cls Closure (connection to keepalive).
971  * @param tc TaskContext.
972  */
973 static void
974 connection_bck_keepalive (void *cls,
975                           const struct GNUNET_SCHEDULER_TaskContext *tc)
976 {
977   struct MeshConnection *c = cls;
978
979   c->bck_maintenance_task = GNUNET_SCHEDULER_NO_TASK;
980   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
981     return;
982
983   connection_maintain (c, GNUNET_NO);
984
985   /* Next execution will be scheduled by message_sent */
986 }
987
988
989 /**
990  * Schedule next keepalive task, taking in consideration
991  * the connection state and number of retries.
992  *
993  * If the peer is not the origin, do nothing.
994  *
995  * @param c Connection for which to schedule the next keepalive.
996  * @param fwd Direction for the next keepalive.
997  */
998 static void
999 schedule_next_keepalive (struct MeshConnection *c, int fwd)
1000 {
1001   struct GNUNET_TIME_Relative delay;
1002   GNUNET_SCHEDULER_TaskIdentifier *task_id;
1003   GNUNET_SCHEDULER_Task keepalive_task;
1004
1005   if (GNUNET_NO == GMC_is_origin (c, fwd))
1006     return;
1007
1008   /* Calculate delay to use, depending on the state of the connection */
1009   if (MESH_CONNECTION_READY == c->state)
1010   {
1011     delay = refresh_connection_time;
1012   }
1013   else
1014   {
1015     if (1 > c->create_retry)
1016       c->create_retry = 1;
1017     delay = GNUNET_TIME_relative_multiply (create_connection_time,
1018                                            c->create_retry);
1019     if (c->create_retry < 64)
1020       c->create_retry *= 2;
1021   }
1022
1023   /* Select direction-dependent parameters */
1024   if (GNUNET_YES == fwd)
1025   {
1026     task_id = &c->fwd_maintenance_task;
1027     keepalive_task = &connection_fwd_keepalive;
1028   }
1029   else
1030   {
1031     task_id = &c->bck_maintenance_task;
1032     keepalive_task = &connection_bck_keepalive;
1033   }
1034
1035   /* Check that no one scheduled it before us (and alert in that case) */
1036   if (GNUNET_SCHEDULER_NO_TASK != *task_id)
1037   {
1038     GNUNET_break (0);
1039     GNUNET_SCHEDULER_cancel (*task_id);
1040   }
1041
1042   /* Schedule the task */
1043   *task_id = GNUNET_SCHEDULER_add_delayed (delay, keepalive_task, c);
1044 }
1045
1046
1047 /**
1048  * @brief Re-initiate traffic on this connection if necessary.
1049  *
1050  * Check if there is traffic queued towards this peer
1051  * and the core transmit handle is NULL (traffic was stalled).
1052  * If so, call core tmt rdy.
1053  *
1054  * @param c Connection on which initiate traffic.
1055  * @param fwd Is this about fwd traffic?
1056  */
1057 static void
1058 connection_unlock_queue (struct MeshConnection *c, int fwd)
1059 {
1060   struct MeshPeer *peer;
1061
1062   LOG (GNUNET_ERROR_TYPE_DEBUG,
1063               "connection_unlock_queue %s on %s\n",
1064               GM_f2s (fwd), GMC_2s (c));
1065
1066   if (GMC_is_terminal (c, fwd))
1067   {
1068     LOG (GNUNET_ERROR_TYPE_DEBUG, " is terminal!\n");
1069     return;
1070   }
1071
1072   peer = get_hop (c, fwd);
1073   GMP_queue_unlock (peer, c);
1074 }
1075
1076
1077 /**
1078  * Cancel all transmissions that belong to a certain connection.
1079  *
1080  * If the connection is scheduled for destruction and no more messages are left,
1081  * the connection will be destroyed by the continuation call.
1082  *
1083  * @param c Connection which to cancel. Might be destroyed during this call.
1084  * @param fwd Cancel fwd traffic?
1085  */
1086 static void
1087 connection_cancel_queues (struct MeshConnection *c, int fwd)
1088 {
1089   struct MeshFlowControl *fc;
1090   struct MeshPeer *peer;
1091
1092   LOG (GNUNET_ERROR_TYPE_DEBUG,
1093        " *** Cancel %s queues for connection %s\n",
1094        GM_f2s (fwd), GMC_2s (c));
1095   if (NULL == c)
1096   {
1097     GNUNET_break (0);
1098     return;
1099   }
1100
1101   fc = fwd ? &c->fwd_fc : &c->bck_fc;
1102   if (GNUNET_SCHEDULER_NO_TASK != fc->poll_task)
1103   {
1104     GNUNET_SCHEDULER_cancel (fc->poll_task);
1105     fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
1106     LOG (GNUNET_ERROR_TYPE_DEBUG, " *** Cancel POLL in ccq for fc %p\n", fc);
1107   }
1108   peer = get_hop (c, fwd);
1109   GMP_queue_cancel (peer, c);
1110 }
1111
1112
1113 /**
1114  * Function called if a connection has been stalled for a while,
1115  * possibly due to a missed ACK. Poll the neighbor about its ACK status.
1116  *
1117  * @param cls Closure (poll ctx).
1118  * @param tc TaskContext.
1119  */
1120 static void
1121 connection_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
1122
1123
1124 /**
1125  * Callback called when a queued POLL message is sent.
1126  *
1127  * @param cls Closure (FC).
1128  * @param c Connection this message was on.
1129  * @param q Queue handler this call invalidates.
1130  * @param type Type of message sent.
1131  * @param fwd Was this a FWD going message?
1132  * @param size Size of the message.
1133  */
1134 static void
1135 poll_sent (void *cls,
1136            struct MeshConnection *c,
1137            struct MeshConnectionQueue *q,
1138            uint16_t type, int fwd, size_t size)
1139 {
1140   struct MeshFlowControl *fc = cls;
1141
1142   if (2 == c->destroy)
1143   {
1144     LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL canceled on shutdown\n");
1145     return;
1146   }
1147   LOG (GNUNET_ERROR_TYPE_DEBUG,
1148        " *** POLL sent for , scheduling new one!\n");
1149   fc->poll_msg = NULL;
1150   fc->poll_time = GNUNET_TIME_STD_BACKOFF (fc->poll_time);
1151   fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
1152                                                 &connection_poll, fc);
1153   LOG (GNUNET_ERROR_TYPE_DEBUG, " task %u\n", fc->poll_task);
1154
1155 }
1156
1157 /**
1158  * Function called if a connection has been stalled for a while,
1159  * possibly due to a missed ACK. Poll the neighbor about its ACK status.
1160  *
1161  * @param cls Closure (poll ctx).
1162  * @param tc TaskContext.
1163  */
1164 static void
1165 connection_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1166 {
1167   struct MeshFlowControl *fc = cls;
1168   struct GNUNET_MESH_Poll msg;
1169   struct MeshConnection *c;
1170
1171   fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
1172   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
1173   {
1174     return;
1175   }
1176
1177   c = fc->c;
1178   LOG (GNUNET_ERROR_TYPE_DEBUG, " *** Polling!\n");
1179   LOG (GNUNET_ERROR_TYPE_DEBUG, " *** connection [%s]\n", GMC_2s (c));
1180   LOG (GNUNET_ERROR_TYPE_DEBUG, " ***   %s\n",
1181        fc == &c->fwd_fc ? "FWD" : "BCK");
1182
1183   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL);
1184   msg.header.size = htons (sizeof (msg));
1185   msg.pid = htonl (fc->last_pid_sent);
1186   LOG (GNUNET_ERROR_TYPE_DEBUG, " *** last pid sent: %u!\n", fc->last_pid_sent);
1187   fc->poll_msg = GMC_send_prebuilt_message (&msg.header, c,
1188                                             fc == &c->fwd_fc, GNUNET_YES,
1189                                             &poll_sent, fc);
1190 }
1191
1192
1193 /**
1194  * Timeout function due to lack of keepalive/traffic from the owner.
1195  * Destroys connection if called.
1196  *
1197  * @param cls Closure (connection to destroy).
1198  * @param tc TaskContext.
1199  */
1200 static void
1201 connection_fwd_timeout (void *cls,
1202                         const struct GNUNET_SCHEDULER_TaskContext *tc)
1203 {
1204   struct MeshConnection *c = cls;
1205
1206   c->fwd_maintenance_task = GNUNET_SCHEDULER_NO_TASK;
1207   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
1208     return;
1209
1210   LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection %s FWD timed out. Destroying.\n",
1211        GMC_2s (c));
1212   if (GMC_is_origin (c, GNUNET_YES)) /* If local, leave. */
1213   {
1214     GNUNET_break (0);
1215     return;
1216   }
1217
1218   GMC_destroy (c);
1219 }
1220
1221
1222 /**
1223  * Timeout function due to lack of keepalive/traffic from the destination.
1224  * Destroys connection if called.
1225  *
1226  * @param cls Closure (connection to destroy).
1227  * @param tc TaskContext
1228  */
1229 static void
1230 connection_bck_timeout (void *cls,
1231                         const struct GNUNET_SCHEDULER_TaskContext *tc)
1232 {
1233   struct MeshConnection *c = cls;
1234
1235   c->bck_maintenance_task = GNUNET_SCHEDULER_NO_TASK;
1236   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
1237     return;
1238
1239   LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection %s BCK timed out. Destroying.\n",
1240        GMC_2s (c));
1241
1242   if (GMC_is_origin (c, GNUNET_NO)) /* If local, leave. */
1243   {
1244     GNUNET_break (0);
1245     return;
1246   }
1247
1248   GMC_destroy (c);
1249 }
1250
1251
1252 /**
1253  * Resets the connection timeout task, some other message has done the
1254  * task's job.
1255  * - For the first peer on the direction this means to send
1256  *   a keepalive or a path confirmation message (either create or ACK).
1257  * - For all other peers, this means to destroy the connection,
1258  *   due to lack of activity.
1259  * Starts the timeout if no timeout was running (connection just created).
1260  *
1261  * @param c Connection whose timeout to reset.
1262  * @param fwd Is this forward?
1263  *
1264  * TODO use heap to improve efficiency of scheduler.
1265  */
1266 static void
1267 connection_reset_timeout (struct MeshConnection *c, int fwd)
1268 {
1269   GNUNET_SCHEDULER_TaskIdentifier *ti;
1270   GNUNET_SCHEDULER_Task f;
1271
1272   ti = fwd ? &c->fwd_maintenance_task : &c->bck_maintenance_task;
1273
1274   LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection %s reset timeout\n", GM_f2s (fwd));
1275
1276   if (GNUNET_SCHEDULER_NO_TASK != *ti)
1277     GNUNET_SCHEDULER_cancel (*ti);
1278
1279   if (GMC_is_origin (c, fwd)) /* Startpoint */
1280   {
1281     f = fwd ? &connection_fwd_keepalive : &connection_bck_keepalive;
1282     *ti = GNUNET_SCHEDULER_add_delayed (refresh_connection_time, f, c);
1283   }
1284   else /* Relay, endpoint. */
1285   {
1286     struct GNUNET_TIME_Relative delay;
1287
1288     delay = GNUNET_TIME_relative_multiply (refresh_connection_time, 4);
1289     f = fwd ? &connection_fwd_timeout : &connection_bck_timeout;
1290     *ti = GNUNET_SCHEDULER_add_delayed (delay, f, c);
1291   }
1292 }
1293
1294
1295 /**
1296  * Add the connection to the list of both neighbors.
1297  *
1298  * @param c Connection.
1299  *
1300  * @return #GNUNET_OK if everything went fine
1301  *         #GNUNET_SYSERR if the was an error and @c c is malformed.
1302  */
1303 static int
1304 register_neighbors (struct MeshConnection *c)
1305 {
1306   struct MeshPeer *next_peer;
1307   struct MeshPeer *prev_peer;
1308
1309   next_peer = get_next_hop (c);
1310   prev_peer = get_prev_hop (c);
1311
1312   LOG (GNUNET_ERROR_TYPE_DEBUG, "register neighbors for connection %s\n",
1313        GMC_2s (c));
1314   path_debug (c->path);
1315   LOG (GNUNET_ERROR_TYPE_DEBUG, "own pos %u\n", c->own_pos);
1316   LOG (GNUNET_ERROR_TYPE_DEBUG, "putting connection %s to next peer %p\n",
1317        GMC_2s (c), next_peer);
1318   LOG (GNUNET_ERROR_TYPE_DEBUG, "next peer %p %s\n", next_peer, GMP_2s (next_peer));
1319   LOG (GNUNET_ERROR_TYPE_DEBUG, "putting connection %s to prev peer %p\n",
1320        GMC_2s (c), prev_peer);
1321   LOG (GNUNET_ERROR_TYPE_DEBUG, "prev peer %p %s\n", prev_peer, GMP_2s (prev_peer));
1322
1323   if (GNUNET_NO == GMP_is_neighbor (next_peer)
1324       || GNUNET_NO == GMP_is_neighbor (prev_peer))
1325   {
1326     if (GMC_is_origin (c, GNUNET_YES))
1327       GNUNET_STATISTICS_update (stats, "# local bad paths", 1, GNUNET_NO);
1328     GNUNET_STATISTICS_update (stats, "# bad paths", 1, GNUNET_NO);
1329
1330     LOG (GNUNET_ERROR_TYPE_DEBUG, "  register neighbors failed\n");
1331     LOG (GNUNET_ERROR_TYPE_DEBUG, "  prev: %s, neighbor?: %d\n",
1332          GMP_2s (prev_peer), GMP_is_neighbor (prev_peer));
1333     LOG (GNUNET_ERROR_TYPE_DEBUG, "  next: %s, neighbor?: %d\n",
1334          GMP_2s (next_peer), GMP_is_neighbor (next_peer));
1335     return GNUNET_SYSERR;
1336   }
1337
1338   GMP_add_connection (next_peer, c);
1339   GMP_add_connection (prev_peer, c);
1340
1341   return GNUNET_OK;
1342 }
1343
1344
1345 /**
1346  * Remove the connection from the list of both neighbors.
1347  *
1348  * @param c Connection.
1349  */
1350 static void
1351 unregister_neighbors (struct MeshConnection *c)
1352 {
1353   struct MeshPeer *peer;
1354
1355   peer = get_next_hop (c);
1356   if (GNUNET_OK != GMP_remove_connection (peer, c))
1357   {
1358     GNUNET_assert (MESH_CONNECTION_NEW == c->state
1359                   || MESH_CONNECTION_DESTROYED == c->state);
1360     LOG (GNUNET_ERROR_TYPE_DEBUG, "  cstate: %u\n", c->state);
1361     if (NULL != c->t) GMT_debug (c->t);
1362   }
1363
1364   peer = get_prev_hop (c);
1365   if (GNUNET_OK != GMP_remove_connection (peer, c))
1366   {
1367     GNUNET_assert (MESH_CONNECTION_NEW == c->state
1368                   || MESH_CONNECTION_DESTROYED == c->state);
1369     LOG (GNUNET_ERROR_TYPE_DEBUG, "  cstate: %u\n", c->state);
1370     if (NULL != c->t) GMT_debug (c->t);
1371   }
1372 }
1373
1374
1375 /**
1376  * Bind the connection to the peer and the tunnel to that peer.
1377  *
1378  * If the peer has no tunnel, create one. Update tunnel and connection
1379  * data structres to reflect new status.
1380  *
1381  * @param c Connection.
1382  * @param peer Peer.
1383  */
1384 static void
1385 add_to_peer (struct MeshConnection *c, struct MeshPeer *peer)
1386 {
1387   GMP_add_tunnel (peer);
1388   c->t = GMP_get_tunnel (peer);
1389   GMT_add_connection (c->t, c);
1390 }
1391
1392
1393 /**
1394  * Builds a path from a PeerIdentity array.
1395  *
1396  * @param peers PeerIdentity array.
1397  * @param size Size of the @c peers array.
1398  * @param own_pos Output parameter: own position in the path.
1399  *
1400  * @return Fixed and shortened path.
1401  */
1402 static struct MeshPeerPath *
1403 build_path_from_peer_ids (struct GNUNET_PeerIdentity *peers,
1404                           unsigned int size,
1405                           unsigned int *own_pos)
1406 {
1407   struct MeshPeerPath *path;
1408   GNUNET_PEER_Id shortid;
1409   unsigned int i;
1410   unsigned int j;
1411   unsigned int offset;
1412
1413   /* Create path */
1414   LOG (GNUNET_ERROR_TYPE_DEBUG, "  Creating path...\n");
1415   path = path_new (size);
1416   *own_pos = 0;
1417   offset = 0;
1418   for (i = 0; i < size; i++)
1419   {
1420     LOG (GNUNET_ERROR_TYPE_DEBUG, "  - %u: taking %s\n",
1421          i, GNUNET_i2s (&peers[i]));
1422     shortid = GNUNET_PEER_intern (&peers[i]);
1423
1424     /* Check for loops / duplicates */
1425     for (j = 0; j < i - offset; j++)
1426     {
1427       if (path->peers[j] == shortid)
1428       {
1429         LOG (GNUNET_ERROR_TYPE_DEBUG, "    already exists at pos %u\n", j);
1430         offset += i - j;
1431         LOG (GNUNET_ERROR_TYPE_DEBUG, "    offset now\n", offset);
1432         GNUNET_PEER_change_rc (shortid, -1);
1433       }
1434     }
1435     LOG (GNUNET_ERROR_TYPE_DEBUG, "    storing at %u\n", i - offset);
1436     path->peers[i - offset] = shortid;
1437     if (path->peers[i] == myid)
1438       *own_pos = i;
1439   }
1440   path->length -= offset;
1441
1442   if (path->peers[*own_pos] != myid)
1443   {
1444     /* create path: self not found in path through self */
1445     GNUNET_break_op (0);
1446     path_destroy (path);
1447     return NULL;
1448   }
1449
1450   return path;
1451 }
1452
1453
1454 /**
1455  * Log receipt of message on stderr (INFO level).
1456  *
1457  * @param message Message received.
1458  * @param peer Peer who sent the message.
1459  */
1460 static void
1461 log_message (const struct GNUNET_MessageHeader *message,
1462              const struct GNUNET_PeerIdentity *peer)
1463 {
1464   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
1465   LOG (GNUNET_ERROR_TYPE_INFO, "Got a %s message from %s\n",
1466        GM_m2s (ntohs (message->type)), GNUNET_i2s (peer));
1467 }
1468
1469 /******************************************************************************/
1470 /********************************    API    ***********************************/
1471 /******************************************************************************/
1472
1473 /**
1474  * Core handler for connection creation.
1475  *
1476  * @param cls Closure (unused).
1477  * @param peer Sender (neighbor).
1478  * @param message Message.
1479  *
1480  * @return GNUNET_OK to keep the connection open,
1481  *         GNUNET_SYSERR to close it (signal serious error)
1482  */
1483 int
1484 GMC_handle_create (void *cls, const struct GNUNET_PeerIdentity *peer,
1485                    const struct GNUNET_MessageHeader *message)
1486 {
1487   struct GNUNET_MESH_ConnectionCreate *msg;
1488   struct GNUNET_PeerIdentity *id;
1489   struct GNUNET_HashCode *cid;
1490   struct MeshPeerPath *path;
1491   struct MeshPeer *dest_peer;
1492   struct MeshPeer *orig_peer;
1493   struct MeshConnection *c;
1494   unsigned int own_pos;
1495   uint16_t size;
1496
1497   log_message (message, peer);
1498
1499   /* Check size */
1500   size = ntohs (message->size);
1501   if (size < sizeof (struct GNUNET_MESH_ConnectionCreate))
1502   {
1503     GNUNET_break_op (0);
1504     return GNUNET_OK;
1505   }
1506
1507   /* Calculate hops */
1508   size -= sizeof (struct GNUNET_MESH_ConnectionCreate);
1509   if (size % sizeof (struct GNUNET_PeerIdentity))
1510   {
1511     GNUNET_break_op (0);
1512     return GNUNET_OK;
1513   }
1514   size /= sizeof (struct GNUNET_PeerIdentity);
1515   if (1 > size)
1516   {
1517     GNUNET_break_op (0);
1518     return GNUNET_OK;
1519   }
1520   LOG (GNUNET_ERROR_TYPE_DEBUG, "    path has %u hops.\n", size);
1521
1522   /* Get parameters */
1523   msg = (struct GNUNET_MESH_ConnectionCreate *) message;
1524   cid = &msg->cid;
1525   id = (struct GNUNET_PeerIdentity *) &msg[1];
1526   LOG (GNUNET_ERROR_TYPE_DEBUG, "    connection %s (%s->).\n",
1527        GNUNET_h2s (cid), GNUNET_i2s (id));
1528
1529   /* Create connection */
1530   c = connection_get (cid);
1531   if (NULL == c)
1532   {
1533     path = build_path_from_peer_ids ((struct GNUNET_PeerIdentity *) &msg[1],
1534                                      size, &own_pos);
1535     if (NULL == path)
1536       return GNUNET_OK;
1537     if (0 == own_pos)
1538     {
1539       GNUNET_break_op (0);
1540       path_destroy (path);
1541       return GNUNET_OK;
1542     }
1543     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Own position: %u\n", own_pos);
1544     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Creating connection\n");
1545     c = GMC_new (cid, NULL, path_duplicate (path), own_pos);
1546     if (NULL == c)
1547     {
1548       if (path->length - 1 == own_pos)
1549       {
1550         /* If we are destination, why did the creation fail? */
1551         GNUNET_break (0);
1552         return GNUNET_OK;
1553       }
1554       send_broken2 (cid, &my_full_id,
1555                     GNUNET_PEER_resolve2 (path->peers[own_pos + 1]),
1556                     path->peers[own_pos - 1]);
1557       path_destroy (path);
1558       return GNUNET_OK;
1559     }
1560     GMP_add_path_to_all (path, GNUNET_NO);
1561     connection_reset_timeout (c, GNUNET_YES);
1562   }
1563   else
1564   {
1565     path = path_duplicate (c->path);
1566   }
1567   if (MESH_CONNECTION_NEW == c->state)
1568     connection_change_state (c, MESH_CONNECTION_SENT);
1569
1570   /* Remember peers */
1571   dest_peer = GMP_get (&id[size - 1]);
1572   orig_peer = GMP_get (&id[0]);
1573
1574   /* Is it a connection to us? */
1575   if (c->own_pos == size - 1)
1576   {
1577     LOG (GNUNET_ERROR_TYPE_DEBUG, "  It's for us!\n");
1578     GMP_add_path_to_origin (orig_peer, path_duplicate (path), GNUNET_YES);
1579
1580     add_to_peer (c, orig_peer);
1581     if (MESH_TUNNEL3_NEW == GMT_get_cstate (c->t))
1582       GMT_change_cstate (c->t,  MESH_TUNNEL3_WAITING);
1583
1584     send_connection_ack (c, GNUNET_NO);
1585     if (MESH_CONNECTION_SENT == c->state)
1586       connection_change_state (c, MESH_CONNECTION_ACK);
1587   }
1588   else
1589   {
1590     /* It's for somebody else! Retransmit. */
1591     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Retransmitting.\n");
1592     GMP_add_path (dest_peer, path_duplicate (path), GNUNET_NO);
1593     GMP_add_path_to_origin (orig_peer, path_duplicate (path), GNUNET_NO);
1594     GMC_send_prebuilt_message (message, c, GNUNET_YES, GNUNET_YES,
1595                                NULL, NULL);
1596   }
1597   path_destroy (path);
1598   return GNUNET_OK;
1599 }
1600
1601
1602 /**
1603  * Core handler for path confirmations.
1604  *
1605  * @param cls closure
1606  * @param message message
1607  * @param peer peer identity this notification is about
1608  *
1609  * @return GNUNET_OK to keep the connection open,
1610  *         GNUNET_SYSERR to close it (signal serious error)
1611  */
1612 int
1613 GMC_handle_confirm (void *cls, const struct GNUNET_PeerIdentity *peer,
1614                     const struct GNUNET_MessageHeader *message)
1615 {
1616   struct GNUNET_MESH_ConnectionACK *msg;
1617   struct MeshConnection *c;
1618   struct MeshPeerPath *p;
1619   struct MeshPeer *pi;
1620   enum MeshConnectionState oldstate;
1621   int fwd;
1622
1623   log_message (message, peer);
1624
1625   msg = (struct GNUNET_MESH_ConnectionACK *) message;
1626   LOG (GNUNET_ERROR_TYPE_DEBUG, "  on connection %s\n",
1627               GNUNET_h2s (&msg->cid));
1628   c = connection_get (&msg->cid);
1629   if (NULL == c)
1630   {
1631     GNUNET_STATISTICS_update (stats, "# control on unknown connection",
1632                               1, GNUNET_NO);
1633     LOG (GNUNET_ERROR_TYPE_DEBUG, "  don't know the connection!\n");
1634     return GNUNET_OK;
1635   }
1636
1637   if (GNUNET_NO != c->destroy)
1638   {
1639     LOG (GNUNET_ERROR_TYPE_DEBUG, "  connection being destroyed\n");
1640     return GNUNET_OK;
1641   }
1642
1643   oldstate = c->state;
1644   LOG (GNUNET_ERROR_TYPE_DEBUG, "  via peer %s\n", GNUNET_i2s (peer));
1645   pi = GMP_get (peer);
1646   if (get_next_hop (c) == pi)
1647   {
1648     LOG (GNUNET_ERROR_TYPE_DEBUG, "  SYNACK\n");
1649     fwd = GNUNET_NO;
1650     if (MESH_CONNECTION_SENT == oldstate)
1651       connection_change_state (c, MESH_CONNECTION_ACK);
1652   }
1653   else if (get_prev_hop (c) == pi)
1654   {
1655     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ACK\n");
1656     fwd = GNUNET_YES;
1657     connection_change_state (c, MESH_CONNECTION_READY);
1658   }
1659   else
1660   {
1661     GNUNET_break_op (0);
1662     return GNUNET_OK;
1663   }
1664
1665   connection_reset_timeout (c, fwd);
1666
1667   /* Add path to peers? */
1668   p = c->path;
1669   if (NULL != p)
1670   {
1671     GMP_add_path_to_all (p, GNUNET_YES);
1672   }
1673   else
1674   {
1675     GNUNET_break (0);
1676   }
1677
1678   /* Message for us as creator? */
1679   if (GMC_is_origin (c, GNUNET_YES))
1680   {
1681     if (GNUNET_NO != fwd)
1682     {
1683       GNUNET_break_op (0);
1684       return GNUNET_OK;
1685     }
1686     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Connection (SYN)ACK for us!\n");
1687
1688     /* If just created, cancel the short timeout and start a long one */
1689     if (MESH_CONNECTION_SENT == oldstate)
1690       connection_reset_timeout (c, GNUNET_YES);
1691
1692     /* Change connection state */
1693     connection_change_state (c, MESH_CONNECTION_READY);
1694     send_connection_ack (c, GNUNET_YES);
1695
1696     /* Change tunnel state, trigger KX */
1697     if (MESH_TUNNEL3_WAITING == GMT_get_cstate (c->t))
1698       GMT_change_cstate (c->t, MESH_TUNNEL3_READY);
1699
1700     return GNUNET_OK;
1701   }
1702
1703   /* Message for us as destination? */
1704   if (GMC_is_terminal (c, GNUNET_YES))
1705   {
1706     if (GNUNET_YES != fwd)
1707     {
1708       GNUNET_break_op (0);
1709       return GNUNET_OK;
1710     }
1711     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Connection ACK for us!\n");
1712
1713     /* If just created, cancel the short timeout and start a long one */
1714     if (MESH_CONNECTION_ACK == oldstate)
1715       connection_reset_timeout (c, GNUNET_NO);
1716
1717     /* Change tunnel state */
1718     if (MESH_TUNNEL3_WAITING == GMT_get_cstate (c->t))
1719       GMT_change_cstate (c->t, MESH_TUNNEL3_READY);
1720
1721     return GNUNET_OK;
1722   }
1723
1724   LOG (GNUNET_ERROR_TYPE_DEBUG, "  not for us, retransmitting...\n");
1725   GMC_send_prebuilt_message (message, c, fwd, GNUNET_YES, NULL, NULL);
1726   return GNUNET_OK;
1727 }
1728
1729
1730 /**
1731  * Core handler for notifications of broken paths
1732  *
1733  * @param cls Closure (unused).
1734  * @param id Peer identity of sending neighbor.
1735  * @param message Message.
1736  *
1737  * @return GNUNET_OK to keep the connection open,
1738  *         GNUNET_SYSERR to close it (signal serious error)
1739  */
1740 int
1741 GMC_handle_broken (void* cls,
1742                    const struct GNUNET_PeerIdentity* id,
1743                    const struct GNUNET_MessageHeader* message)
1744 {
1745   struct GNUNET_MESH_ConnectionBroken *msg;
1746   struct MeshConnection *c;
1747   int fwd;
1748
1749   log_message (message, id);
1750
1751   msg = (struct GNUNET_MESH_ConnectionBroken *) message;
1752   LOG (GNUNET_ERROR_TYPE_DEBUG, "  regarding %s\n",
1753               GNUNET_i2s (&msg->peer1));
1754   LOG (GNUNET_ERROR_TYPE_DEBUG, "  regarding %s\n",
1755               GNUNET_i2s (&msg->peer2));
1756   c = connection_get (&msg->cid);
1757   if (NULL == c)
1758   {
1759     GNUNET_break_op (0);
1760     return GNUNET_OK;
1761   }
1762
1763   fwd = is_fwd (c, id);
1764   if (GMC_is_terminal (c, fwd))
1765   {
1766     path_invalidate (c->path);
1767     if (0 < c->pending_messages)
1768       c->destroy = GNUNET_YES;
1769     else
1770       GMC_destroy (c);
1771   }
1772   else
1773   {
1774     GMC_send_prebuilt_message (message, c, fwd, GNUNET_YES, NULL, NULL);
1775     c->destroy = GNUNET_YES;
1776     connection_cancel_queues (c, !fwd);
1777   }
1778
1779   return GNUNET_OK;
1780
1781 }
1782
1783
1784 /**
1785  * Core handler for tunnel destruction
1786  *
1787  * @param cls Closure (unused).
1788  * @param peer Peer identity of sending neighbor.
1789  * @param message Message.
1790  *
1791  * @return GNUNET_OK to keep the connection open,
1792  *         GNUNET_SYSERR to close it (signal serious error)
1793  */
1794 int
1795 GMC_handle_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
1796                     const struct GNUNET_MessageHeader *message)
1797 {
1798   struct GNUNET_MESH_ConnectionDestroy *msg;
1799   struct MeshConnection *c;
1800   int fwd;
1801
1802   log_message (message, peer);
1803
1804   msg = (struct GNUNET_MESH_ConnectionDestroy *) message;
1805   LOG (GNUNET_ERROR_TYPE_DEBUG, "  on connection %s\n", GNUNET_h2s (&msg->cid));
1806   c = connection_get (&msg->cid);
1807   if (NULL == c)
1808   {
1809     /* Probably already got the message from another path,
1810      * destroyed the tunnel and retransmitted to children.
1811      * Safe to ignore.
1812      */
1813     GNUNET_STATISTICS_update (stats, "# control on unknown connection",
1814                               1, GNUNET_NO);
1815     LOG (GNUNET_ERROR_TYPE_DEBUG, "  connection unknown: already destroyed?\n");
1816     return GNUNET_OK;
1817   }
1818   fwd = is_fwd (c, peer);
1819   if (GNUNET_SYSERR == fwd)
1820   {
1821     GNUNET_break_op (0); /* FIXME */
1822     return GNUNET_OK;
1823   }
1824   if (GNUNET_NO == GMC_is_terminal (c, fwd))
1825     GMC_send_prebuilt_message (message, c, fwd, GNUNET_YES, NULL, NULL);
1826   else if (0 == c->pending_messages)
1827   {
1828     LOG (GNUNET_ERROR_TYPE_DEBUG, "!  directly destroying connection!\n");
1829     GMC_destroy (c);
1830     return GNUNET_OK;
1831   }
1832   c->destroy = GNUNET_YES;
1833   c->state = MESH_CONNECTION_DESTROYED;
1834   if (NULL != c->t)
1835   {
1836     GMT_remove_connection (c->t, c);
1837     c->t = NULL;
1838   }
1839
1840   return GNUNET_OK;
1841 }
1842
1843 /**
1844  * Generic handler for mesh network encrypted traffic.
1845  *
1846  * @param peer Peer identity this notification is about.
1847  * @param msg Encrypted message.
1848  *
1849  * @return GNUNET_OK to keep the connection open,
1850  *         GNUNET_SYSERR to close it (signal serious error)
1851  */
1852 static int
1853 handle_mesh_encrypted (const struct GNUNET_PeerIdentity *peer,
1854                        const struct GNUNET_MESH_Encrypted *msg)
1855 {
1856   struct MeshConnection *c;
1857   struct MeshPeer *neighbor;
1858   struct MeshFlowControl *fc;
1859   GNUNET_PEER_Id peer_id;
1860   uint32_t pid;
1861   uint32_t ttl;
1862   size_t size;
1863   int fwd;
1864
1865   /* Check size */
1866   size = ntohs (msg->header.size);
1867   if (size <
1868       sizeof (struct GNUNET_MESH_Encrypted) +
1869       sizeof (struct GNUNET_MessageHeader))
1870   {
1871     GNUNET_break_op (0);
1872     return GNUNET_OK;
1873   }
1874
1875   /* Check connection */
1876   c = connection_get (&msg->cid);
1877   if (NULL == c)
1878   {
1879     GNUNET_STATISTICS_update (stats, "# unknown connection", 1, GNUNET_NO);
1880     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING enc on unknown connection %s\n",
1881          GNUNET_h2s (&msg->cid));
1882     return GNUNET_OK;
1883   }
1884
1885   LOG (GNUNET_ERROR_TYPE_INFO, "  on connection %s\n", GMC_2s (c));
1886
1887   /* Check if origin is as expected */
1888   neighbor = get_prev_hop (c);
1889   peer_id = GNUNET_PEER_search (peer);
1890   if (peer_id == GMP_get_short_id (neighbor))
1891   {
1892     fwd = GNUNET_YES;
1893   }
1894   else
1895   {
1896     neighbor = get_next_hop (c);
1897     if (peer_id == GMP_get_short_id (neighbor))
1898     {
1899       fwd = GNUNET_NO;
1900     }
1901     else
1902     {
1903       /* Unexpected peer sending traffic on a connection. */
1904       GNUNET_break_op (0);
1905       return GNUNET_OK;
1906     }
1907   }
1908
1909   /* Check PID */
1910   fc = fwd ? &c->bck_fc : &c->fwd_fc;
1911   pid = ntohl (msg->pid);
1912   if (GM_is_pid_bigger (pid, fc->last_ack_sent))
1913   {
1914     GNUNET_STATISTICS_update (stats, "# unsolicited message", 1, GNUNET_NO);
1915     LOG (GNUNET_ERROR_TYPE_DEBUG,
1916                 "WARNING Received PID %u, (prev %u), ACK %u\n",
1917                 pid, fc->last_pid_recv, fc->last_ack_sent);
1918     return GNUNET_OK;
1919   }
1920   if (GNUNET_NO == GM_is_pid_bigger (pid, fc->last_pid_recv))
1921   {
1922     GNUNET_STATISTICS_update (stats, "# duplicate PID", 1, GNUNET_NO);
1923     LOG (GNUNET_ERROR_TYPE_DEBUG,
1924                 " Pid %u not expected (%u+), dropping!\n",
1925                 pid, fc->last_pid_recv + 1);
1926     return GNUNET_OK;
1927   }
1928   if (MESH_CONNECTION_SENT == c->state || MESH_CONNECTION_ACK == c->state)
1929     connection_change_state (c, MESH_CONNECTION_READY);
1930   connection_reset_timeout (c, fwd);
1931   fc->last_pid_recv = pid;
1932
1933   /* Is this message for us? */
1934   if (GMC_is_terminal (c, fwd))
1935   {
1936     LOG (GNUNET_ERROR_TYPE_DEBUG, "  message for us!\n");
1937     GNUNET_STATISTICS_update (stats, "# messages received", 1, GNUNET_NO);
1938
1939     if (NULL == c->t)
1940     {
1941       GNUNET_break (GNUNET_NO != c->destroy);
1942       return GNUNET_OK;
1943     }
1944     fc->last_pid_recv = pid;
1945     GMT_handle_encrypted (c->t, msg);
1946     GMC_send_ack (c, fwd, GNUNET_NO);
1947     return GNUNET_OK;
1948   }
1949
1950   /* Message not for us: forward to next hop */
1951   LOG (GNUNET_ERROR_TYPE_DEBUG, "  not for us, retransmitting...\n");
1952   ttl = ntohl (msg->ttl);
1953   LOG (GNUNET_ERROR_TYPE_DEBUG, "   ttl: %u\n", ttl);
1954   if (ttl == 0)
1955   {
1956     GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
1957     LOG (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
1958     GMC_send_ack (c, fwd, GNUNET_NO);
1959     return GNUNET_OK;
1960   }
1961
1962   GNUNET_STATISTICS_update (stats, "# messages forwarded", 1, GNUNET_NO);
1963   GMC_send_prebuilt_message (&msg->header, c, fwd, GNUNET_NO, NULL, NULL);
1964
1965   return GNUNET_OK;
1966 }
1967
1968 /**
1969  * Generic handler for mesh network encrypted traffic.
1970  *
1971  * @param peer Peer identity this notification is about.
1972  * @param msg Encrypted message.
1973  *
1974  * @return GNUNET_OK to keep the connection open,
1975  *         GNUNET_SYSERR to close it (signal serious error)
1976  */
1977 static int
1978 handle_mesh_kx (const struct GNUNET_PeerIdentity *peer,
1979                 const struct GNUNET_MESH_KX *msg)
1980 {
1981   struct MeshConnection *c;
1982   struct MeshPeer *neighbor;
1983   GNUNET_PEER_Id peer_id;
1984   size_t size;
1985   int fwd;
1986
1987   /* Check size */
1988   size = ntohs (msg->header.size);
1989   if (size <
1990       sizeof (struct GNUNET_MESH_Encrypted) +
1991       sizeof (struct GNUNET_MessageHeader))
1992   {
1993     GNUNET_break_op (0);
1994     return GNUNET_OK;
1995   }
1996
1997   /* Check connection */
1998   c = connection_get (&msg->cid);
1999   if (NULL == c)
2000   {
2001     GNUNET_STATISTICS_update (stats, "# unknown connection", 1, GNUNET_NO);
2002     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING kx on unknown connection %s\n",
2003          GNUNET_h2s (&msg->cid));
2004     return GNUNET_OK;
2005   }
2006   LOG (GNUNET_ERROR_TYPE_DEBUG, " on connection %s\n", GMC_2s (c));
2007
2008   /* Check if origin is as expected */
2009   neighbor = get_prev_hop (c);
2010   peer_id = GNUNET_PEER_search (peer);
2011   if (peer_id == GMP_get_short_id (neighbor))
2012   {
2013     fwd = GNUNET_YES;
2014   }
2015   else
2016   {
2017     neighbor = get_next_hop (c);
2018     if (peer_id == GMP_get_short_id (neighbor))
2019     {
2020       fwd = GNUNET_NO;
2021     }
2022     else
2023     {
2024       /* Unexpected peer sending traffic on a connection. */
2025       GNUNET_break_op (0);
2026       return GNUNET_OK;
2027     }
2028   }
2029
2030   /* Count as connection confirmation. */
2031   if (MESH_CONNECTION_SENT == c->state || MESH_CONNECTION_ACK == c->state)
2032   {
2033     connection_change_state (c, MESH_CONNECTION_READY);
2034     if (NULL != c->t)
2035     {
2036       if (MESH_TUNNEL3_WAITING == GMT_get_cstate (c->t))
2037         GMT_change_cstate (c->t, MESH_TUNNEL3_READY);
2038     }
2039   }
2040   connection_reset_timeout (c, fwd);
2041
2042   /* Is this message for us? */
2043   if (GMC_is_terminal (c, fwd))
2044   {
2045     LOG (GNUNET_ERROR_TYPE_DEBUG, "  message for us!\n");
2046     GNUNET_STATISTICS_update (stats, "# messages received", 1, GNUNET_NO);
2047     if (NULL == c->t)
2048     {
2049       GNUNET_break (0);
2050       return GNUNET_OK;
2051     }
2052     GMT_handle_kx (c->t, &msg[1].header);
2053     return GNUNET_OK;
2054   }
2055
2056   /* Message not for us: forward to next hop */
2057   LOG (GNUNET_ERROR_TYPE_DEBUG, "  not for us, retransmitting...\n");
2058   GNUNET_STATISTICS_update (stats, "# messages forwarded", 1, GNUNET_NO);
2059   GMC_send_prebuilt_message (&msg->header, c, fwd, GNUNET_NO, NULL, NULL);
2060
2061   return GNUNET_OK;
2062 }
2063
2064
2065 /**
2066  * Core handler for encrypted mesh network traffic (channel mgmt, data).
2067  *
2068  * @param cls Closure (unused).
2069  * @param message Message received.
2070  * @param peer Peer who sent the message.
2071  *
2072  * @return GNUNET_OK to keep the connection open,
2073  *         GNUNET_SYSERR to close it (signal serious error)
2074  */
2075 int
2076 GMC_handle_encrypted (void *cls, const struct GNUNET_PeerIdentity *peer,
2077                       const struct GNUNET_MessageHeader *message)
2078 {
2079   log_message (message, peer);
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   log_message (message, peer);
2101
2102   return handle_mesh_kx (peer,
2103                          (struct GNUNET_MESH_KX *) message);
2104 }
2105
2106
2107 /**
2108  * Core handler for mesh network traffic point-to-point acks.
2109  *
2110  * @param cls closure
2111  * @param message message
2112  * @param peer peer identity this notification is about
2113  *
2114  * @return GNUNET_OK to keep the connection open,
2115  *         GNUNET_SYSERR to close it (signal serious error)
2116  */
2117 int
2118 GMC_handle_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
2119                 const struct GNUNET_MessageHeader *message)
2120 {
2121   struct GNUNET_MESH_ACK *msg;
2122   struct MeshConnection *c;
2123   struct MeshFlowControl *fc;
2124   GNUNET_PEER_Id id;
2125   uint32_t ack;
2126   int fwd;
2127
2128   log_message (message, peer);
2129
2130   msg = (struct GNUNET_MESH_ACK *) message;
2131   c = connection_get (&msg->cid);
2132   if (NULL == c)
2133   {
2134     GNUNET_STATISTICS_update (stats, "# ack on unknown connection", 1,
2135                               GNUNET_NO);
2136     return GNUNET_OK;
2137   }
2138
2139   /* Is this a forward or backward ACK? */
2140   id = GNUNET_PEER_search (peer);
2141   if (GMP_get_short_id (get_next_hop (c)) == id)
2142   {
2143     LOG (GNUNET_ERROR_TYPE_DEBUG, "  FWD ACK\n");
2144     fc = &c->fwd_fc;
2145     fwd = GNUNET_YES;
2146   }
2147   else if (GMP_get_short_id (get_prev_hop (c)) == id)
2148   {
2149     LOG (GNUNET_ERROR_TYPE_DEBUG, "  BCK ACK\n");
2150     fc = &c->bck_fc;
2151     fwd = GNUNET_NO;
2152   }
2153   else
2154   {
2155     GNUNET_break_op (0);
2156     return GNUNET_OK;
2157   }
2158
2159   ack = ntohl (msg->ack);
2160   LOG (GNUNET_ERROR_TYPE_DEBUG, "  ACK %u (was %u)\n",
2161               ack, fc->last_ack_recv);
2162   if (GM_is_pid_bigger (ack, fc->last_ack_recv))
2163     fc->last_ack_recv = ack;
2164
2165   /* Cancel polling if the ACK is big enough. */
2166   if (GNUNET_SCHEDULER_NO_TASK != fc->poll_task &&
2167       GM_is_pid_bigger (fc->last_ack_recv, fc->last_pid_sent))
2168   {
2169     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Cancel poll\n");
2170     GNUNET_SCHEDULER_cancel (fc->poll_task);
2171     fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
2172     fc->poll_time = GNUNET_TIME_UNIT_SECONDS;
2173   }
2174
2175   connection_unlock_queue (c, fwd);
2176
2177   return GNUNET_OK;
2178 }
2179
2180
2181 /**
2182  * Core handler for mesh network traffic point-to-point ack polls.
2183  *
2184  * @param cls closure
2185  * @param message message
2186  * @param peer peer identity this notification is about
2187  *
2188  * @return GNUNET_OK to keep the connection open,
2189  *         GNUNET_SYSERR to close it (signal serious error)
2190  */
2191 int
2192 GMC_handle_poll (void *cls, const struct GNUNET_PeerIdentity *peer,
2193                  const struct GNUNET_MessageHeader *message)
2194 {
2195   struct GNUNET_MESH_Poll *msg;
2196   struct MeshConnection *c;
2197   struct MeshFlowControl *fc;
2198   GNUNET_PEER_Id id;
2199   uint32_t pid;
2200   int fwd;
2201
2202   log_message (message, peer);
2203
2204   msg = (struct GNUNET_MESH_Poll *) message;
2205   c = connection_get (&msg->cid);
2206   if (NULL == c)
2207   {
2208     GNUNET_STATISTICS_update (stats, "# poll on unknown connection", 1,
2209                               GNUNET_NO);
2210     LOG (GNUNET_ERROR_TYPE_DEBUG,
2211          "WARNING POLL message on unknown connection %s!\n",
2212          GNUNET_h2s (&msg->cid));
2213     return GNUNET_OK;
2214   }
2215
2216   /* Is this a forward or backward ACK?
2217    * Note: a poll should never be needed in a loopback case,
2218    * since there is no possiblility of packet loss there, so
2219    * this way of discerining FWD/BCK should not be a problem.
2220    */
2221   id = GNUNET_PEER_search (peer);
2222   if (GMP_get_short_id (get_next_hop (c)) == id)
2223   {
2224     LOG (GNUNET_ERROR_TYPE_DEBUG, "  FWD FC\n");
2225     fc = &c->fwd_fc;
2226   }
2227   else if (GMP_get_short_id (get_prev_hop (c)) == id)
2228   {
2229     LOG (GNUNET_ERROR_TYPE_DEBUG, "  BCK FC\n");
2230     fc = &c->bck_fc;
2231   }
2232   else
2233   {
2234     GNUNET_break_op (0);
2235     return GNUNET_OK;
2236   }
2237
2238   pid = ntohl (msg->pid);
2239   LOG (GNUNET_ERROR_TYPE_DEBUG, "  PID %u, OLD %u\n", pid, fc->last_pid_recv);
2240   fc->last_pid_recv = pid;
2241   fwd = fc == &c->bck_fc;
2242   GMC_send_ack (c, fwd, GNUNET_YES);
2243
2244   return GNUNET_OK;
2245 }
2246
2247
2248 /**
2249  * Core handler for mesh keepalives.
2250  *
2251  * @param cls closure
2252  * @param message message
2253  * @param peer peer identity this notification is about
2254  * @return GNUNET_OK to keep the connection open,
2255  *         GNUNET_SYSERR to close it (signal serious error)
2256  *
2257  * TODO: Check who we got this from, to validate route.
2258  */
2259 int
2260 GMC_handle_keepalive (void *cls, const struct GNUNET_PeerIdentity *peer,
2261                       const struct GNUNET_MessageHeader *message)
2262 {
2263   struct GNUNET_MESH_ConnectionKeepAlive *msg;
2264   struct MeshConnection *c;
2265   struct MeshPeer *neighbor;
2266   GNUNET_PEER_Id peer_id;
2267   int fwd;
2268
2269   log_message (message, peer);
2270
2271   msg = (struct GNUNET_MESH_ConnectionKeepAlive *) message;
2272   c = connection_get (&msg->cid);
2273   if (NULL == c)
2274   {
2275     GNUNET_STATISTICS_update (stats, "# keepalive on unknown connection", 1,
2276                               GNUNET_NO);
2277     return GNUNET_OK;
2278   }
2279
2280   /* Check if origin is as expected TODO refactor and reuse */
2281   peer_id = GNUNET_PEER_search (peer);
2282   neighbor = get_prev_hop (c);
2283   if (peer_id == GMP_get_short_id (neighbor))
2284   {
2285     fwd = GNUNET_YES;
2286   }
2287   else
2288   {
2289     neighbor = get_next_hop (c);
2290     if (peer_id == GMP_get_short_id (neighbor))
2291     {
2292       fwd = GNUNET_NO;
2293     }
2294     else
2295     {
2296       GNUNET_break_op (0);
2297       return GNUNET_OK;
2298     }
2299   }
2300
2301   connection_change_state (c, MESH_CONNECTION_READY);
2302   connection_reset_timeout (c, fwd);
2303
2304   if (GMC_is_terminal (c, fwd))
2305     return GNUNET_OK;
2306
2307   GNUNET_STATISTICS_update (stats, "# keepalives forwarded", 1, GNUNET_NO);
2308   GMC_send_prebuilt_message (message, c, fwd, GNUNET_YES, NULL, NULL);
2309
2310   return GNUNET_OK;
2311 }
2312
2313
2314 /**
2315  * Send an ACK on the appropriate connection/channel, depending on
2316  * the direction and the position of the peer.
2317  *
2318  * @param c Which connection to send the hop-by-hop ACK.
2319  * @param fwd Is this a fwd ACK? (will go dest->root).
2320  * @param force Send the ACK even if suboptimal (e.g. requested by POLL).
2321  */
2322 void
2323 GMC_send_ack (struct MeshConnection *c, int fwd, int force)
2324 {
2325   unsigned int buffer;
2326
2327   LOG (GNUNET_ERROR_TYPE_DEBUG,
2328        "GMC send %s ACK on %s\n",
2329        GM_f2s (fwd), GMC_2s (c));
2330
2331   if (NULL == c)
2332   {
2333     GNUNET_break (0);
2334     return;
2335   }
2336
2337   if (GNUNET_NO != c->destroy)
2338   {
2339     LOG (GNUNET_ERROR_TYPE_DEBUG, "  being destroyed, why bother...\n");
2340     return;
2341   }
2342
2343   /* Get available buffer space */
2344   if (GMC_is_terminal (c, fwd))
2345   {
2346     LOG (GNUNET_ERROR_TYPE_DEBUG, "  getting from all channels\n");
2347     buffer = GMT_get_channels_buffer (c->t);
2348   }
2349   else
2350   {
2351     LOG (GNUNET_ERROR_TYPE_DEBUG, "  getting from one connection\n");
2352     buffer = GMC_get_buffer (c, fwd);
2353   }
2354   LOG (GNUNET_ERROR_TYPE_DEBUG, "  buffer available: %u\n", buffer);
2355   if (0 == buffer && GNUNET_NO == force)
2356     return;
2357
2358   /* Send available buffer space */
2359   if (GMC_is_origin (c, fwd))
2360   {
2361     GNUNET_assert (NULL != c->t);
2362     LOG (GNUNET_ERROR_TYPE_DEBUG, "  sending on channels...\n");
2363     GMT_unchoke_channels (c->t);
2364   }
2365   else
2366   {
2367     LOG (GNUNET_ERROR_TYPE_DEBUG, "  sending on connection\n");
2368     send_ack (c, buffer, fwd, force);
2369   }
2370 }
2371
2372
2373 /**
2374  * Initialize the connections subsystem
2375  *
2376  * @param c Configuration handle.
2377  */
2378 void
2379 GMC_init (const struct GNUNET_CONFIGURATION_Handle *c)
2380 {
2381   LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
2382   if (GNUNET_OK !=
2383       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_MSGS_QUEUE",
2384                                              &max_msgs_queue))
2385   {
2386     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
2387                                "MESH", "MAX_MSGS_QUEUE", "MISSING");
2388     GNUNET_SCHEDULER_shutdown ();
2389     return;
2390   }
2391
2392   if (GNUNET_OK !=
2393       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_CONNECTIONS",
2394                                              &max_connections))
2395   {
2396     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
2397                                "MESH", "MAX_CONNECTIONS", "MISSING");
2398     GNUNET_SCHEDULER_shutdown ();
2399     return;
2400   }
2401
2402   if (GNUNET_OK !=
2403       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "REFRESH_CONNECTION_TIME",
2404                                            &refresh_connection_time))
2405   {
2406     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
2407                                "MESH", "REFRESH_CONNECTION_TIME", "MISSING");
2408     GNUNET_SCHEDULER_shutdown ();
2409     return;
2410   }
2411   create_connection_time = GNUNET_TIME_UNIT_SECONDS;
2412   connections = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_YES);
2413 }
2414
2415
2416 /**
2417  * Destroy each connection on shutdown.
2418  *
2419  * @param cls Closure (unused).
2420  * @param key Current key code (CID, unused).
2421  * @param value Value in the hash map (connection)
2422  *
2423  * @return #GNUNET_YES, because we should continue to iterate,
2424  */
2425 static int
2426 shutdown_iterator (void *cls,
2427                    const struct GNUNET_HashCode *key,
2428                    void *value)
2429 {
2430   struct MeshConnection *c = value;
2431
2432   GMC_destroy (c);
2433   return GNUNET_YES;
2434 }
2435
2436
2437 /**
2438  * Shut down the connections subsystem.
2439  */
2440 void
2441 GMC_shutdown (void)
2442 {
2443   GNUNET_CONTAINER_multihashmap_iterate (connections, &shutdown_iterator, NULL);
2444   GNUNET_CONTAINER_multihashmap_destroy (connections);
2445   connections = NULL;
2446 }
2447
2448
2449 struct MeshConnection *
2450 GMC_new (const struct GNUNET_HashCode *cid,
2451          struct MeshTunnel3 *t,
2452          struct MeshPeerPath *p,
2453          unsigned int own_pos)
2454 {
2455   struct MeshConnection *c;
2456
2457   c = GNUNET_new (struct MeshConnection);
2458   c->id = *cid;
2459   GNUNET_assert (GNUNET_OK ==
2460                  GNUNET_CONTAINER_multihashmap_put (connections,
2461                                                     &c->id, c,
2462                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
2463   fc_init (&c->fwd_fc);
2464   fc_init (&c->bck_fc);
2465   c->fwd_fc.c = c;
2466   c->bck_fc.c = c;
2467
2468   c->t = t;
2469   GNUNET_assert (own_pos <= p->length - 1);
2470   c->own_pos = own_pos;
2471   c->path = p;
2472
2473   if (GNUNET_OK != register_neighbors (c))
2474   {
2475     if (0 == own_pos)
2476     {
2477       path_invalidate (c->path);
2478       c->t = NULL;
2479       c->path = NULL;
2480     }
2481     GMC_destroy (c);
2482     return NULL;
2483   }
2484
2485   return c;
2486 }
2487
2488
2489 void
2490 GMC_destroy (struct MeshConnection *c)
2491 {
2492   if (NULL == c)
2493   {
2494     GNUNET_break (0);
2495     return;
2496   }
2497
2498   if (2 == c->destroy) /* cancel queues -> GMP_queue_cancel -> q_destroy -> */
2499     return;            /* -> message_sent -> GMC_destroy. Don't loop. */
2500   c->destroy = 2;
2501
2502   LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying connection %s\n", GMC_2s (c));
2503   LOG (GNUNET_ERROR_TYPE_DEBUG, " fc's f: %p, b: %p\n",
2504        &c->fwd_fc, &c->bck_fc);
2505   LOG (GNUNET_ERROR_TYPE_DEBUG, " fc tasks f: %u, b: %u\n",
2506        c->fwd_fc.poll_task, c->bck_fc.poll_task);
2507
2508   /* Cancel all traffic */
2509   if (NULL != c->path)
2510   {
2511     connection_cancel_queues (c, GNUNET_YES);
2512     connection_cancel_queues (c, GNUNET_NO);
2513     unregister_neighbors (c);
2514   }
2515
2516   LOG (GNUNET_ERROR_TYPE_DEBUG, " fc tasks f: %u, b: %u\n",
2517        c->fwd_fc.poll_task, c->bck_fc.poll_task);
2518
2519   /* Cancel maintainance task (keepalive/timeout) */
2520   if (NULL != c->fwd_fc.poll_msg)
2521   {
2522     GMC_cancel (c->fwd_fc.poll_msg);
2523     LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL msg FWD canceled\n");
2524   }
2525   if (NULL != c->bck_fc.poll_msg)
2526   {
2527     GMC_cancel (c->bck_fc.poll_msg);
2528     LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL msg BCK canceled\n");
2529   }
2530
2531   /* Delete from tunnel */
2532   if (NULL != c->t)
2533     GMT_remove_connection (c->t, c);
2534
2535   if (GNUNET_NO == GMC_is_origin (c, GNUNET_YES) && NULL != c->path)
2536     path_destroy (c->path);
2537   if (GNUNET_SCHEDULER_NO_TASK != c->fwd_maintenance_task)
2538     GNUNET_SCHEDULER_cancel (c->fwd_maintenance_task);
2539   if (GNUNET_SCHEDULER_NO_TASK != c->bck_maintenance_task)
2540     GNUNET_SCHEDULER_cancel (c->bck_maintenance_task);
2541   if (GNUNET_SCHEDULER_NO_TASK != c->fwd_fc.poll_task)
2542   {
2543     GNUNET_SCHEDULER_cancel (c->fwd_fc.poll_task);
2544     LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL FWD canceled\n");
2545   }
2546   if (GNUNET_SCHEDULER_NO_TASK != c->bck_fc.poll_task)
2547   {
2548     GNUNET_SCHEDULER_cancel (c->bck_fc.poll_task);
2549     LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL BCK canceled\n");
2550   }
2551
2552   GNUNET_break (GNUNET_YES ==
2553                 GNUNET_CONTAINER_multihashmap_remove (connections, &c->id, c));
2554
2555   GNUNET_STATISTICS_update (stats, "# connections", -1, GNUNET_NO);
2556   GNUNET_free (c);
2557 }
2558
2559 /**
2560  * Get the connection ID.
2561  *
2562  * @param c Connection to get the ID from.
2563  *
2564  * @return ID of the connection.
2565  */
2566 const struct GNUNET_HashCode *
2567 GMC_get_id (const struct MeshConnection *c)
2568 {
2569   return &c->id;
2570 }
2571
2572
2573 /**
2574  * Get the connection path.
2575  *
2576  * @param c Connection to get the path from.
2577  *
2578  * @return path used by the connection.
2579  */
2580 const struct MeshPeerPath *
2581 GMC_get_path (const struct MeshConnection *c)
2582 {
2583   if (GNUNET_NO == c->destroy)
2584     return c->path;
2585   return NULL;
2586 }
2587
2588
2589 /**
2590  * Get the connection state.
2591  *
2592  * @param c Connection to get the state from.
2593  *
2594  * @return state of the connection.
2595  */
2596 enum MeshConnectionState
2597 GMC_get_state (const struct MeshConnection *c)
2598 {
2599   return c->state;
2600 }
2601
2602 /**
2603  * Get the connection tunnel.
2604  *
2605  * @param c Connection to get the tunnel from.
2606  *
2607  * @return tunnel of the connection.
2608  */
2609 struct MeshTunnel3 *
2610 GMC_get_tunnel (const struct MeshConnection *c)
2611 {
2612   return c->t;
2613 }
2614
2615
2616 /**
2617  * Get free buffer space in a connection.
2618  *
2619  * @param c Connection.
2620  * @param fwd Is query about FWD traffic?
2621  *
2622  * @return Free buffer space [0 - max_msgs_queue/max_connections]
2623  */
2624 unsigned int
2625 GMC_get_buffer (struct MeshConnection *c, int fwd)
2626 {
2627   struct MeshFlowControl *fc;
2628
2629   fc = fwd ? &c->fwd_fc : &c->bck_fc;
2630
2631   return (fc->queue_max - fc->queue_n);
2632 }
2633
2634 /**
2635  * Get how many messages have we allowed to send to us from a direction.
2636  *
2637  * @param c Connection.
2638  * @param fwd Are we asking about traffic from FWD (BCK messages)?
2639  *
2640  * @return last_ack_sent - last_pid_recv
2641  */
2642 unsigned int
2643 GMC_get_allowed (struct MeshConnection *c, int fwd)
2644 {
2645   struct MeshFlowControl *fc;
2646
2647   fc = fwd ? &c->fwd_fc : &c->bck_fc;
2648   if (GM_is_pid_bigger(fc->last_pid_recv, fc->last_ack_sent))
2649   {
2650     return 0;
2651   }
2652   return (fc->last_ack_sent - fc->last_pid_recv);
2653 }
2654
2655 /**
2656  * Get messages queued in a connection.
2657  *
2658  * @param c Connection.
2659  * @param fwd Is query about FWD traffic?
2660  *
2661  * @return Number of messages queued.
2662  */
2663 unsigned int
2664 GMC_get_qn (struct MeshConnection *c, int fwd)
2665 {
2666   struct MeshFlowControl *fc;
2667
2668   fc = fwd ? &c->fwd_fc : &c->bck_fc;
2669
2670   return fc->queue_n;
2671 }
2672
2673
2674 /**
2675  * Allow the connection to advertise a buffer of the given size.
2676  *
2677  * The connection will send an @c fwd ACK message (so: in direction !fwd)
2678  * allowing up to last_pid_recv + buffer.
2679  *
2680  * @param c Connection.
2681  * @param buffer How many more messages the connection can accept.
2682  * @param fwd Is this about FWD traffic? (The ack will go dest->root).
2683  */
2684 void
2685 GMC_allow (struct MeshConnection *c, unsigned int buffer, int fwd)
2686 {
2687   LOG (GNUNET_ERROR_TYPE_DEBUG, "  allowing %s %u messages %s\n",
2688        GMC_2s (c), buffer, GM_f2s (fwd));
2689   send_ack (c, buffer, fwd, GNUNET_NO);
2690 }
2691
2692
2693 /**
2694  * Notify other peers on a connection of a broken link. Mark connections
2695  * to destroy after all traffic has been sent.
2696  *
2697  * @param c Connection on which there has been a disconnection.
2698  * @param peer Peer that disconnected.
2699  */
2700 void
2701 GMC_notify_broken (struct MeshConnection *c,
2702                    struct MeshPeer *peer)
2703 {
2704   int fwd;
2705
2706   LOG (GNUNET_ERROR_TYPE_DEBUG,
2707        " notify broken on %s due to %s disconnect\n",
2708        GMC_2s (c), GMP_2s (peer));
2709
2710   fwd = peer == get_prev_hop (c);
2711
2712   if (GNUNET_YES == GMC_is_terminal (c, fwd))
2713   {
2714     /* Local shutdown, no one to notify about this. */
2715     GMC_destroy (c);
2716     return;
2717   }
2718   if (GNUNET_NO == c->destroy)
2719     send_broken (c, &my_full_id, GMP_get_id (peer), fwd);
2720
2721   /* Connection will have at least one pending message
2722    * (the one we just scheduled), so no point in checking whether to
2723    * destroy immediately. */
2724   c->destroy = GNUNET_YES;
2725   c->state = MESH_CONNECTION_DESTROYED;
2726
2727   /**
2728    * Cancel all queues, if no message is left, connection will be destroyed.
2729    */
2730   connection_cancel_queues (c, !fwd);
2731
2732   return;
2733 }
2734
2735
2736 /**
2737  * Is this peer the first one on the connection?
2738  *
2739  * @param c Connection.
2740  * @param fwd Is this about fwd traffic?
2741  *
2742  * @return #GNUNET_YES if origin, #GNUNET_NO if relay/terminal.
2743  */
2744 int
2745 GMC_is_origin (struct MeshConnection *c, int fwd)
2746 {
2747   if (!fwd && c->path->length - 1 == c->own_pos )
2748     return GNUNET_YES;
2749   if (fwd && 0 == c->own_pos)
2750     return GNUNET_YES;
2751   return GNUNET_NO;
2752 }
2753
2754
2755 /**
2756  * Is this peer the last one on the connection?
2757  *
2758  * @param c Connection.
2759  * @param fwd Is this about fwd traffic?
2760  *            Note that the ROOT is the terminal for BCK traffic!
2761  *
2762  * @return #GNUNET_YES if terminal, #GNUNET_NO if relay/origin.
2763  */
2764 int
2765 GMC_is_terminal (struct MeshConnection *c, int fwd)
2766 {
2767   return GMC_is_origin (c, !fwd);
2768 }
2769
2770
2771 /**
2772  * See if we are allowed to send by the next hop in the given direction.
2773  *
2774  * @param c Connection.
2775  * @param fwd Is this about fwd traffic?
2776  *
2777  * @return #GNUNET_YES in case it's OK to send.
2778  */
2779 int
2780 GMC_is_sendable (struct MeshConnection *c, int fwd)
2781 {
2782   struct MeshFlowControl *fc;
2783
2784   if (NULL == c)
2785   {
2786     GNUNET_break (0);
2787     return GNUNET_YES;
2788   }
2789   fc = fwd ? &c->fwd_fc : &c->bck_fc;
2790   if (GM_is_pid_bigger (fc->last_ack_recv, fc->last_pid_sent))
2791     return GNUNET_YES;
2792   return GNUNET_NO;
2793 }
2794
2795 /**
2796  * Sends an already built message on a connection, properly registering
2797  * all used resources.
2798  *
2799  * @param message Message to send. Function makes a copy of it.
2800  *                If message is not hop-by-hop, decrements TTL of copy.
2801  * @param c Connection on which this message is transmitted.
2802  * @param fwd Is this a fwd message?
2803  * @param force Force the connection to accept the message (buffer overfill).
2804  * @param cont Continuation called once message is sent. Can be NULL.
2805  * @param cont_cls Closure for @c cont.
2806  *
2807  * @return Handle to cancel the message before it's sent.
2808  *         NULL on error or if @c cont is NULL.
2809  *         Invalid on @c cont call.
2810  */
2811 struct MeshConnectionQueue *
2812 GMC_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
2813                            struct MeshConnection *c, int fwd, int force,
2814                            GMC_sent cont, void *cont_cls)
2815 {
2816   struct MeshFlowControl *fc;
2817   struct MeshConnectionQueue *q;
2818   void *data;
2819   size_t size;
2820   uint16_t type;
2821   int droppable;
2822
2823   size = ntohs (message->size);
2824   data = GNUNET_malloc (size);
2825   memcpy (data, message, size);
2826   type = ntohs (message->type);
2827   LOG (GNUNET_ERROR_TYPE_INFO, "Send %s (%u bytes) on connection %s\n",
2828        GM_m2s (type), size, GMC_2s (c));
2829
2830   fc = fwd ? &c->fwd_fc : &c->bck_fc;
2831   droppable = GNUNET_NO == force;
2832   switch (type)
2833   {
2834     struct GNUNET_MESH_Encrypted *emsg;
2835     struct GNUNET_MESH_KX        *kmsg;
2836     struct GNUNET_MESH_ACK       *amsg;
2837     struct GNUNET_MESH_Poll      *pmsg;
2838     struct GNUNET_MESH_ConnectionDestroy *dmsg;
2839     struct GNUNET_MESH_ConnectionBroken  *bmsg;
2840     uint32_t ttl;
2841
2842     case GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED:
2843       emsg = (struct GNUNET_MESH_Encrypted *) data;
2844       ttl = ntohl (emsg->ttl);
2845       if (0 == ttl)
2846       {
2847         GNUNET_break_op (0);
2848         GNUNET_free (data);
2849         return NULL;
2850       }
2851       emsg->cid = c->id;
2852       emsg->ttl = htonl (ttl - 1);
2853       emsg->pid = htonl (fc->next_pid++);
2854       LOG (GNUNET_ERROR_TYPE_DEBUG, "  Q_N+ %p %u\n", fc, fc->queue_n);
2855       if (GNUNET_YES == droppable)
2856       {
2857         fc->queue_n++;
2858         LOG (GNUNET_ERROR_TYPE_DEBUG, "pid %u\n", ntohl (emsg->pid));
2859         LOG (GNUNET_ERROR_TYPE_DEBUG, "last pid sent %u\n", fc->last_pid_sent);
2860         LOG (GNUNET_ERROR_TYPE_DEBUG, "     ack recv %u\n", fc->last_ack_recv);
2861       }
2862       else
2863       {
2864         LOG (GNUNET_ERROR_TYPE_DEBUG, "  not droppable, Q_N stays the same\n");
2865       }
2866       if (GM_is_pid_bigger (fc->last_pid_sent + 1, fc->last_ack_recv))
2867       {
2868         GMC_start_poll (c, fwd);
2869       }
2870       break;
2871
2872     case GNUNET_MESSAGE_TYPE_MESH_KX:
2873       kmsg = (struct GNUNET_MESH_KX *) data;
2874       kmsg->cid = c->id;
2875       break;
2876
2877     case GNUNET_MESSAGE_TYPE_MESH_ACK:
2878       amsg = (struct GNUNET_MESH_ACK *) data;
2879       amsg->cid = c->id;
2880       LOG (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ntohl (amsg->ack));
2881       droppable = GNUNET_NO;
2882       break;
2883
2884     case GNUNET_MESSAGE_TYPE_MESH_POLL:
2885       pmsg = (struct GNUNET_MESH_Poll *) data;
2886       pmsg->cid = c->id;
2887       LOG (GNUNET_ERROR_TYPE_DEBUG, " poll %u\n", ntohl (pmsg->pid));
2888       droppable = GNUNET_NO;
2889       break;
2890
2891     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_DESTROY:
2892       dmsg = (struct GNUNET_MESH_ConnectionDestroy *) data;
2893       dmsg->cid = c->id;
2894       dmsg->reserved = 0;
2895       break;
2896
2897     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN:
2898       bmsg = (struct GNUNET_MESH_ConnectionBroken *) data;
2899       bmsg->cid = c->id;
2900       bmsg->reserved = 0;
2901       break;
2902
2903     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE:
2904     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK:
2905     case GNUNET_MESSAGE_TYPE_MESH_KEEPALIVE:
2906       break;
2907
2908     default:
2909       GNUNET_break (0);
2910       GNUNET_free (data);
2911       return NULL;
2912   }
2913
2914   if (fc->queue_n > fc->queue_max && droppable)
2915   {
2916     GNUNET_STATISTICS_update (stats, "# messages dropped (buffer full)",
2917                               1, GNUNET_NO);
2918     GNUNET_break (0);
2919     LOG (GNUNET_ERROR_TYPE_DEBUG,
2920                 "queue full: %u/%u\n",
2921                 fc->queue_n, fc->queue_max);
2922     if (GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED == type)
2923     {
2924       fc->queue_n--;
2925       fc->next_pid--;
2926     }
2927     GNUNET_free (data);
2928     return NULL; /* Drop this message */
2929   }
2930
2931   LOG (GNUNET_ERROR_TYPE_DEBUG, "  C_P+ %p %u\n", c, c->pending_messages);
2932   c->pending_messages++;
2933
2934   q = GNUNET_new (struct MeshConnectionQueue);
2935   q->forced = !droppable;
2936   q->q = GMP_queue_add (get_hop (c, fwd), data, type, size, c, fwd,
2937                         &message_sent, q);
2938   if (NULL == q->q)
2939   {
2940     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING dropping msg on %s\n", GMC_2s (c));
2941     GNUNET_free (data);
2942     GNUNET_free (q);
2943     return NULL;
2944   }
2945   q->cont = cont;
2946   q->cont_cls = cont_cls;
2947   return q;
2948 }
2949
2950
2951 /**
2952  * Cancel a previously sent message while it's in the queue.
2953  *
2954  * ONLY can be called before the continuation given to the send function
2955  * is called. Once the continuation is called, the message is no longer in the
2956  * queue.
2957  *
2958  * @param q Handle to the queue.
2959  */
2960 void
2961 GMC_cancel (struct MeshConnectionQueue *q)
2962 {
2963   LOG (GNUNET_ERROR_TYPE_DEBUG, "!  GMC cancel message\n");
2964
2965   /* queue destroy calls message_sent, which calls q->cont and frees q */
2966   GMP_queue_destroy (q->q, GNUNET_YES);
2967 }
2968
2969
2970 /**
2971  * Sends a CREATE CONNECTION message for a path to a peer.
2972  * Changes the connection and tunnel states if necessary.
2973  *
2974  * @param connection Connection to create.
2975  */
2976 void
2977 GMC_send_create (struct MeshConnection *connection)
2978 {
2979   enum MeshTunnel3CState state;
2980   size_t size;
2981
2982   size = sizeof (struct GNUNET_MESH_ConnectionCreate);
2983   size += connection->path->length * sizeof (struct GNUNET_PeerIdentity);
2984
2985   LOG (GNUNET_ERROR_TYPE_INFO, "Send %s (%u bytes) on connection %s\n",
2986        GM_m2s (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE),
2987        size, GMC_2s (connection));
2988   LOG (GNUNET_ERROR_TYPE_DEBUG, "  C_P+ %p %u (create)\n",
2989        connection, connection->pending_messages);
2990   connection->pending_messages++;
2991
2992   connection->maintenance_q =
2993     GMP_queue_add (get_next_hop (connection), NULL,
2994                    GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE,
2995                    size, connection, GNUNET_YES, &message_sent, NULL);
2996
2997   state = GMT_get_cstate (connection->t);
2998   if (MESH_TUNNEL3_SEARCHING == state || MESH_TUNNEL3_NEW == state)
2999     GMT_change_cstate (connection->t, MESH_TUNNEL3_WAITING);
3000   if (MESH_CONNECTION_NEW == connection->state)
3001     connection_change_state (connection, MESH_CONNECTION_SENT);
3002 }
3003
3004
3005 /**
3006  * Send a message to all peers in this connection that the connection
3007  * is no longer valid.
3008  *
3009  * If some peer should not receive the message, it should be zero'ed out
3010  * before calling this function.
3011  *
3012  * @param c The connection whose peers to notify.
3013  */
3014 void
3015 GMC_send_destroy (struct MeshConnection *c)
3016 {
3017   struct GNUNET_MESH_ConnectionDestroy msg;
3018
3019   if (GNUNET_YES == c->destroy)
3020     return;
3021
3022   msg.header.size = htons (sizeof (msg));
3023   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_DESTROY);;
3024   msg.cid = c->id;
3025   LOG (GNUNET_ERROR_TYPE_DEBUG,
3026               "  sending connection destroy for connection %s\n",
3027               GMC_2s (c));
3028
3029   if (GNUNET_NO == GMC_is_terminal (c, GNUNET_YES))
3030     GMC_send_prebuilt_message (&msg.header, c,
3031                                GNUNET_YES, GNUNET_YES, NULL, NULL);
3032   if (GNUNET_NO == GMC_is_terminal (c, GNUNET_NO))
3033     GMC_send_prebuilt_message (&msg.header, c,
3034                                GNUNET_NO, GNUNET_YES, NULL, NULL);
3035   c->destroy = GNUNET_YES;
3036   c->state = MESH_CONNECTION_DESTROYED;
3037 }
3038
3039
3040 /**
3041  * @brief Start a polling timer for the connection.
3042  *
3043  * When a neighbor does not accept more traffic on the connection it could be
3044  * caused by a simple congestion or by a lost ACK. Polling enables to check
3045  * for the lastest ACK status for a connection.
3046  *
3047  * @param c Connection.
3048  * @param fwd Should we poll in the FWD direction?
3049  */
3050 void
3051 GMC_start_poll (struct MeshConnection *c, int fwd)
3052 {
3053   struct MeshFlowControl *fc;
3054
3055   fc = fwd ? &c->fwd_fc : &c->bck_fc;
3056   LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL %s requested\n",
3057        GM_f2s (fwd));
3058   if (GNUNET_SCHEDULER_NO_TASK != fc->poll_task || NULL != fc->poll_msg)
3059   {
3060     LOG (GNUNET_ERROR_TYPE_DEBUG, " ***   not needed (%u, %p)\n",
3061          fc->poll_task, fc->poll_msg);
3062     return;
3063   }
3064   LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL started on request\n");
3065   fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
3066                                                 &connection_poll,
3067                                                 fc);
3068 }
3069
3070
3071 /**
3072  * @brief Stop polling a connection for ACKs.
3073  *
3074  * Once we have enough ACKs for future traffic, polls are no longer necessary.
3075  *
3076  * @param c Connection.
3077  * @param fwd Should we stop the poll in the FWD direction?
3078  */
3079 void
3080 GMC_stop_poll (struct MeshConnection *c, int fwd)
3081 {
3082   struct MeshFlowControl *fc;
3083
3084   fc = fwd ? &c->fwd_fc : &c->bck_fc;
3085   if (GNUNET_SCHEDULER_NO_TASK != fc->poll_task)
3086   {
3087     GNUNET_SCHEDULER_cancel (fc->poll_task);
3088     fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
3089   }
3090 }
3091
3092 /**
3093  * Get a (static) string for a connection.
3094  *
3095  * @param c Connection.
3096  */
3097 const char *
3098 GMC_2s (const struct MeshConnection *c)
3099 {
3100   if (NULL == c)
3101     return "NULL";
3102
3103   if (NULL != c->t)
3104   {
3105     static char buf[128];
3106
3107     sprintf (buf, "%s (->%s)", GNUNET_h2s (&c->id), GMT_2s (c->t));
3108     return buf;
3109   }
3110   return GNUNET_h2s (&c->id);
3111 }