From a85261acba2c59241458bff597db815de85fa771 Mon Sep 17 00:00:00 2001 From: Bart Polot Date: Fri, 11 Oct 2013 15:20:28 +0000 Subject: - backport --- src/mesh/gnunet-service-mesh_connection.c | 34 ++++++++++++++--- src/mesh/gnunet-service-mesh_connection.h | 11 ++++++ src/mesh/gnunet-service-mesh_tunnel.c | 63 +++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 5 deletions(-) (limited to 'src/mesh') diff --git a/src/mesh/gnunet-service-mesh_connection.c b/src/mesh/gnunet-service-mesh_connection.c index 910b5f1f3..94813adf2 100644 --- a/src/mesh/gnunet-service-mesh_connection.c +++ b/src/mesh/gnunet-service-mesh_connection.c @@ -520,8 +520,8 @@ connection_send_ack (struct MeshConnection *c, unsigned int buffer, int fwd) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, buffer > 3\n"); LOG (GNUNET_ERROR_TYPE_DEBUG, - " last pid recv: %u, last ack sent: %u\n", - prev_fc->last_pid_recv, prev_fc->last_ack_sent); + " last pid recv: %u, last ack sent: %u\n", + prev_fc->last_pid_recv, prev_fc->last_ack_sent); return; } @@ -530,9 +530,9 @@ connection_send_ack (struct MeshConnection *c, unsigned int buffer, int fwd) ack = prev_fc->last_pid_recv + delta; LOG (GNUNET_ERROR_TYPE_DEBUG, " ACK %u\n", ack); LOG (GNUNET_ERROR_TYPE_DEBUG, - " last pid %u, last ack %u, qmax %u, q %u\n", - prev_fc->last_pid_recv, prev_fc->last_ack_sent, - next_fc->queue_max, next_fc->queue_n); + " last pid %u, last ack %u, qmax %u, q %u\n", + prev_fc->last_pid_recv, prev_fc->last_ack_sent, + next_fc->queue_max, next_fc->queue_n); if (ack == prev_fc->last_ack_sent) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, not needed\n"); @@ -1663,6 +1663,8 @@ GMC_send_ack (struct MeshConnection *c, struct MeshChannel *ch, int fwd) LOG (GNUNET_ERROR_TYPE_DEBUG, "send ack %s on %p %p\n", fwd ? "FWD" : "BCK", c, ch); + + /* Get available bufffer space */ if (NULL == c || GMC_is_terminal (c, fwd)) { struct MeshTunnel3 *t; @@ -1677,6 +1679,7 @@ GMC_send_ack (struct MeshConnection *c, struct MeshChannel *ch, int fwd) } LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer available: %u\n", buffer); + /* Send available buffer space */ if ( (NULL != ch && GMCH_is_origin (ch, fwd)) || (NULL != c && GMC_is_origin (c, fwd)) ) { @@ -1890,6 +1893,27 @@ GMC_get_buffer (struct MeshConnection *c, int fwd) return (fc->queue_max - fc->queue_n); } +/** + * Get how many messages have we allowed to send to us from a direction.. + * + * @param c Connection. + * @param fwd Are we asking about traffic from FWD (BCK messages)? + * + * @return last_ack_sent - last_pid_recv + */ +unsigned int +GMC_get_allowed (struct MeshConnection *c, int fwd) +{ + struct MeshFlowControl *fc; + + fc = fwd ? &c->fwd_fc : &c->bck_fc; + if (GMC_is_pid_bigger(fc->last_pid_recv, fc->last_ack_sent)) + { + return 0; + } + return (fc->last_ack_sent - fc->last_pid_recv); +} + /** * Get messages queued in a connection. * diff --git a/src/mesh/gnunet-service-mesh_connection.h b/src/mesh/gnunet-service-mesh_connection.h index b55d55fe6..a617054ff 100644 --- a/src/mesh/gnunet-service-mesh_connection.h +++ b/src/mesh/gnunet-service-mesh_connection.h @@ -305,6 +305,17 @@ GMC_get_tunnel (const struct MeshConnection *c); unsigned int GMC_get_buffer (struct MeshConnection *c, int fwd); +/** + * Get how many messages have we allowed to send to us from a direction.. + * + * @param c Connection. + * @param fwd Are we asking about traffic from FWD (BCK messages)? + * + * @return last_ack_sent - last_pid_recv + */ +unsigned int +GMC_get_allowed (struct MeshConnection *c, int fwd); + /** * Get messages queued in a connection. * diff --git a/src/mesh/gnunet-service-mesh_tunnel.c b/src/mesh/gnunet-service-mesh_tunnel.c index 9a25db089..105317501 100644 --- a/src/mesh/gnunet-service-mesh_tunnel.c +++ b/src/mesh/gnunet-service-mesh_tunnel.c @@ -1018,7 +1018,10 @@ GMT_get_buffer (struct MeshTunnel3 *t, int fwd) unsigned int ch_buf; if (NULL == t->channel_head) + { + /* Probably getting buffer for a channel create. */ return 64; + } for (iter_ch = t->channel_head; NULL != iter_ch; iter_ch = iter_ch->next) { @@ -1084,6 +1087,66 @@ GMT_get_next_chid (struct MeshTunnel3 *t) } +/** + * Send ACK on one or more connections due to buffer space to the client. + * + * Iterates all connections of the tunnel and sends ACKs appropriately. + * + * @param ch Channel which has some free buffer space. + * @param fwd Is this in for FWD traffic? (ACK goes dest->root) + */ +static void +GMT_send_acks (struct MeshTunnel3 *t, + unsigned int buffer, + int fwd) +{ + struct MeshTConnection *iter; + uint32_t allowed; + uint32_t to_allow; + uint32_t allow_per_connection; + unsigned int cs; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Tunnel send acks on %s:%X\n", + fwd ? "FWD" : "BCK", peer2s (ch->t->peer), ch->gid); + + /* Count connections, how many messages are already allowed */ + cs = GMT_count_connections (t); + for (allowed = 0, iter = t->connection_head; NULL != iter; iter = iter->next) + { + allowed += GMC_get_allowed (iter->c, fwd); + } + + /* Make sure there is no overflow */ + if (allowed > buffer) + { + GNUNET_break (0); + return; + } + + /* Authorize connections to send more data */ + to_allow = buffer - allowed; + + for (iter = t->connection_head; NULL != iter && to_allow > 0; iter = iter->next) + { + allow_per_connection = to_allow/cs; + to_allow -= allow_per_connection; + cs--; + if (GMC_get_allowed (iter->c, fwd) > 64 / 3) + { + continue; + } + GMC_send_ack (iter->c, NULL, fwd); + connection_send_ack (iter, allow_per_connection, fwd); + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Channel send connection %s ack on %s:%X\n", + fwd ? "FWD" : "BCK", peer2s (ch->t->peer), ch->gid); + GNUNET_break (to_allow == 0); +} + + /** * Sends an already built message on a tunnel, GMT_encrypting it and * choosing the best connection. -- cgit v1.2.3