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