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