};
-/**
- * Info collected during iteration of child nodes in order to get the ACK value
- * for a tunnel.
- */
-struct MeshTunnelChildIteratorContext
-{
- /**
- * Tunnel whose info is being collected.
- */
- struct MeshTunnel *t;
-
- /**
- * Maximum child ACK so far.
- */
- uint32_t max_child_ack;
-
- /**
- * Number of children nodes
- */
- unsigned int nchildren;
-};
-
-
/**
* Struct containing all information regarding a tunnel
* For an intermediate node the improtant info used will be:
struct MeshClient **clients;
/**
- * ACK value of each active client.
+ * FWD ACK value of each active client: up to what message can we transmit
+ * to a leaf client.
*/
uint32_t *clients_acks;
/**
+ * BCK ACK value of the root client, owner of the tunnel,
+ * up to what message PID can we sent him.
+ */
+ uint32_t root_client_ack;
+
+ /**
* Number of elements in clients/clients_acks
*/
unsigned int nclients;
GNUNET_PEER_Id id;
/**
- * SKIP value
+ * SKIP value.
*/
uint32_t skip;
uint32_t max_pid;
};
+
+/**
+ * Info collected during iteration of child nodes in order to get the ACK value
+ * for a tunnel.
+ */
+struct MeshTunnelChildIteratorContext
+{
+ /**
+ * Tunnel whose info is being collected.
+ */
+ struct MeshTunnel *t;
+
+ /**
+ * Maximum child ACK so far.
+ */
+ uint32_t max_child_ack;
+
+ /**
+ * Number of children nodes
+ */
+ unsigned int nchildren;
+};
+
+
/**
* Info needed to work with tunnel paths and peers
*/
/**
- * Notify a client about how many more payload packages will we accept
- * on a given tunnel.
+ * Notify a the client of a tunnel about how many more
+ * payload packages will we accept on a given tunnel,
+ * distinguiching between root and leaf clients.
*
- * @param c Client.
- * @param t Tunnel.
+ * @param c Client whom to send the ACK.
+ * @param t Tunnel on which to send the ACK.
*/
static void
send_client_tunnel_ack (struct MeshClient *c, struct MeshTunnel *t)
{
struct GNUNET_MESH_LocalAck msg;
+ MESH_TunnelNumber tid;
uint32_t ack;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " to client %u\n", c->id);
- ack = tunnel_get_fwd_ack (t);
+ if (c == t->owner)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " (owner, FWD ACK)\n");
+ ack = tunnel_get_fwd_ack (t);
+ tid = t->local_tid;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " (leaf, BCK ACK)\n");
+ ack = tunnel_get_bck_ack (t);
+ tid = t->local_tid_dest;
+ }
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ack);
if (t->last_ack == ack)
t->last_ack = ack;
msg.header.size = htons (sizeof (msg));
msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
- msg.tunnel_id = htonl (t->local_tid);
+ msg.tunnel_id = htonl (tid);
msg.max_pid = htonl (ack);
GNUNET_SERVER_notification_context_unicast (nc, c->handle,
* @param ack ACK value.
*/
static void
-tunnel_set_client_ack (struct MeshTunnel *t,
- struct MeshClient *c,
- uint32_t ack)
+tunnel_set_client_fwd_ack (struct MeshTunnel *t,
+ struct MeshClient *c,
+ uint32_t ack)
{
unsigned int i;
t->queue_max = (max_msgs_queue / max_tunnels) + 1;
t->tree = tree_new (owner);
t->owner = client;
+ t->root_client_ack = 1;
t->local_tid = local;
t->children_fc = GNUNET_CONTAINER_multihashmap_create (8);
n_tunnels++;
/**
- * Handler for client ACKs for payload traffic.
+ * Handler for client's ACKs for payload traffic.
*
* @param cls Closure (unused).
* @param client Identification of the client.
struct MeshClient *c;
MESH_TunnelNumber tid;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a local ACK\n");
/* Sanity check for client registration */
if (NULL == (c = client_get (client)))
{
msg = (struct GNUNET_MESH_LocalAck *) message;
/* Tunnel exists? */
tid = ntohl (msg->tunnel_id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %X\n", tid);
t = tunnel_get_by_local_id (c, tid);
if (NULL == t)
{
return;
}
- /* Does client own tunnel? */
+ /* Does client own tunnel? Is this and ACK for BCK traffic? */
if (NULL != t->owner && t->owner->handle == client)
{
GNUNET_break (0);
}
else
{
- tunnel_set_client_ack (t, c, ntohl (msg->max_pid));
+ /* The client doesn't own the tunnel, this ACK is for FWD traffic. */
+ tunnel_set_client_fwd_ack (t, c, ntohl (msg->max_pid));
+ tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
}
GNUNET_SERVER_receive_done (client, GNUNET_OK);