+/**
+ * Add a client to a tunnel, initializing all needed data structures.
+ *
+ * @param t Tunnel to which add the client.
+ * @param c Client which to add to the tunnel.
+ */
+static void
+tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c)
+{
+ uint32_t ack;
+
+ GNUNET_array_append (t->clients, t->nclients, c);
+ t->nclients--;
+ ack = t->pid + 1;
+ GNUNET_array_append (t->clients_acks, t->nclients, ack);
+}
+
+
+/**
+ * Set the ACK value of a client in a particular tunnel.
+ *
+ * @param t Tunnel affected.
+ * @param c Client whose ACK to set.
+ * @param ack ACK value.
+ */
+static void
+tunnel_set_client_ack (struct MeshTunnel *t,
+ struct MeshClient *c,
+ uint32_t ack)
+{
+ unsigned int i;
+
+ for (i = 0; i < t->nclients; i++)
+ {
+ if (t->clients[i] != c)
+ continue;
+ t->clients_acks[i] = ack;
+ return;
+ }
+ GNUNET_break (0);
+}
+
+
+/**
+ * Get the ACK value of a client in a particular tunnel.
+ *
+ * @param t Tunnel on which to look.
+ * @param c Client whose ACK to get.
+ *
+ * @return ACK value.
+ */
+uint32_t // FIXME static when used!!
+tunnel_get_client_ack (struct MeshTunnel *t,
+ struct MeshClient *c)
+{
+ unsigned int i;
+
+ for (i = 0; i < t->nclients; i++)
+ {
+ if (t->clients[i] != c)
+ continue;
+ return t->clients_acks[i];
+ }
+ GNUNET_break (0);
+ return t->clients_acks[0];
+}
+
+
+/**
+ * Get the highest ACK value of all clients in a particular tunnel,
+ * according to the buffering/speed settings.
+ *
+ * @param t Tunnel on which to look.
+ *
+ * @return Corresponding ACK value.
+ */
+static uint32_t
+tunnel_get_clients_ack (struct MeshTunnel *t)
+{
+ unsigned int i;
+ uint32_t ack;
+
+ for (ack = 0, i = 0; i < t->nclients; i++)
+ {
+ if (0 == ack ||
+ (GNUNET_YES == t->speed_min && t->clients_acks[i] < ack) ||
+ (GNUNET_NO == t->speed_min && t->clients_acks[i] > ack))
+ {
+ ack = t->clients_acks[i];
+ }
+ }
+
+ if (GNUNET_YES == t->nobuffer && ack > t->pid)
+ ack = t->pid + 1;
+
+ return ack;
+}
+
+