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