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