From 1eecfe59914c7c549e666198080b0523a4609004 Mon Sep 17 00:00:00 2001 From: Bart Polot Date: Fri, 27 Jul 2012 11:35:36 +0000 Subject: [PATCH] - wip flow control service<-> client --- src/mesh/gnunet-service-mesh.c | 88 +++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 16 deletions(-) diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index f163bbb09..114dc8d6a 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c @@ -975,6 +975,18 @@ tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1, GNUNET_PEER_Id p2); +/** + * Get the current ack value for a tunnel, taking in account the tunnel + * mode and the status of all children nodes. + * + * @param t Tunnel. + * + * @return Maximum PID allowed. + */ +static uint32_t +tunnel_get_ack (struct MeshTunnel *t); + + /** * Iterator over edges in a regex block retrieved from the DHT. * @@ -1918,6 +1930,31 @@ send_client_peer_connected (const struct MeshTunnel *t, const GNUNET_PEER_Id id) } +/** + * Notify a client about how many more payload packages will we accept + * on a given tunnel. + * + * @param c Client. + * @param t Tunnel. + */ +static void +send_client_tunnel_ack (struct MeshClient *c, struct MeshTunnel *t) +{ + struct GNUNET_MESH_LocalAck msg; + uint32_t ack; + + ack = tunnel_get_ack (t); + + msg.header.size = htons (sizeof (msg)); + msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK); + msg.tunnel_id = htonl (t->local_tid); + msg.max_pid = ack; + + GNUNET_SERVER_notification_context_unicast (nc, c->handle, + &msg.header, GNUNET_NO); +} + + /** * Notify all clients (not depending on registration status) that the incoming * tunnel is no longer valid. @@ -3227,6 +3264,39 @@ tunnel_get_children_ack (struct MeshTunnel *t) } +/** + * Get the current ack value for a tunnel, taking in account the tunnel + * mode and the status of all children nodes. + * + * @param t Tunnel. + * + * @return Maximum PID allowed. + */ +static uint32_t +tunnel_get_ack (struct MeshTunnel *t) +{ + uint32_t count; + uint32_t buffer_free; + uint32_t child_ack; + uint32_t ack; + + count = t->pid - t->skip; + buffer_free = t->queue_max - t->queue_n; + ack = count + buffer_free; + child_ack = tunnel_get_children_ack (t); + + if (GNUNET_YES == t->speed_min) + { + ack = child_ack > ack ? ack : child_ack; + } + else + { + ack = child_ack > ack ? child_ack : ack; + } + return ack; +} + + /** * Send an ACK informing the predecessor about the available buffer space. * If buffering is off, send only on behalf of children or self if endpoint. @@ -3239,9 +3309,6 @@ tunnel_send_ack (struct MeshTunnel *t, uint16_t type) { struct GNUNET_MESH_ACK msg; struct GNUNET_PeerIdentity id; - uint32_t count; - uint32_t buffer_free; - uint32_t child_ack; uint32_t ack; /* Is it after unicast / multicast retransmission? */ @@ -3261,19 +3328,7 @@ tunnel_send_ack (struct MeshTunnel *t, uint16_t type) } /* Ok, ACK might be necessary, what PID to ACK? */ - count = t->pid - t->skip; - buffer_free = t->queue_max - t->queue_n; - ack = count + buffer_free; - child_ack = tunnel_get_children_ack (t); - - if (GNUNET_YES == t->speed_min) - { - ack = child_ack > ack ? ack : child_ack; - } - else - { - ack = child_ack > ack ? child_ack : ack; - } + ack = tunnel_get_ack (t); /* If speed_min and not all children have ack'd, dont send yet */ if (ack == t->last_ack) @@ -6187,6 +6242,7 @@ handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " calling generic handler...\n"); handle_mesh_data_unicast (NULL, &my_full_id, ©->header, NULL, 0); + send_client_tunnel_ack (t->owner, t); } GNUNET_SERVER_receive_done (client, GNUNET_OK); return; -- 2.25.1