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