From 660b35f5117993c1ab0d3d0afa3fb4a26fb54346 Mon Sep 17 00:00:00 2001 From: Simon Wilkinson Date: Wed, 12 Oct 2011 09:50:18 -0400 Subject: [PATCH] rx: ackall handling If we ACKALL a stream, then we're sending a hard ACK for all of the packets in the stream. We shouldn't send that hard ACK, and then a load of soft ACKs for packets that don't actually exist. Reviewed-on: http://gerrit.openafs.org/5604 Reviewed-by: Derrick Brashear Tested-by: BuildBot (cherry picked from commit a9924ba433f81bfbfc2c0e726f2be06d460e4d56) Change-Id: Ibba1d5448f2ba9315b6b9bc3e893d16d8bcdbc3c Reviewed-on: http://gerrit.openafs.org/5714 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/rx/rx.c | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/rx/rx.c b/src/rx/rx.c index 7e5e1172e..bb42e75fc 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -5479,7 +5479,7 @@ rxi_SendAck(struct rx_call *call, struct rx_packet *rqp; struct rx_packet *nxp; /* For queue_Scan */ struct rx_packet *p; - u_char offset; + u_char offset = 0; afs_int32 templ; afs_uint32 padbytes = 0; #ifdef RX_ENABLE_TSFPQ @@ -5587,37 +5587,38 @@ rxi_SendAck(struct rx_call *call, if ((call->flags & RX_CALL_ACKALL_SENT) && !queue_IsEmpty(&call->rq)) { ap->firstPacket = htonl(queue_Last(&call->rq, rx_packet)->header.seq + 1); - } else + } else { ap->firstPacket = htonl(call->rnext); - ap->previousPacket = htonl(call->rprev); /* Previous packet received */ + ap->previousPacket = htonl(call->rprev); /* Previous packet received */ - /* No fear of running out of ack packet here because there can only be at most - * one window full of unacknowledged packets. The window size must be constrained - * to be less than the maximum ack size, of course. Also, an ack should always - * fit into a single packet -- it should not ever be fragmented. */ - for (offset = 0, queue_Scan(&call->rq, rqp, nxp, rx_packet)) { - if (!rqp || !call->rq.next - || (rqp->header.seq > (call->rnext + call->rwind))) { + /* No fear of running out of ack packet here because there can only be at most + * one window full of unacknowledged packets. The window size must be constrained + * to be less than the maximum ack size, of course. Also, an ack should always + * fit into a single packet -- it should not ever be fragmented. */ + for (offset = 0, queue_Scan(&call->rq, rqp, nxp, rx_packet)) { + if (!rqp || !call->rq.next + || (rqp->header.seq > (call->rnext + call->rwind))) { #ifndef RX_ENABLE_TSFPQ - if (!optionalPacket) - rxi_FreePacket(p); + if (!optionalPacket) + rxi_FreePacket(p); #endif - rxi_CallError(call, RX_CALL_DEAD); - return optionalPacket; - } + rxi_CallError(call, RX_CALL_DEAD); + return optionalPacket; + } - while (rqp->header.seq > call->rnext + offset) - ap->acks[offset++] = RX_ACK_TYPE_NACK; - ap->acks[offset++] = RX_ACK_TYPE_ACK; + while (rqp->header.seq > call->rnext + offset) + ap->acks[offset++] = RX_ACK_TYPE_NACK; + ap->acks[offset++] = RX_ACK_TYPE_ACK; - if ((offset > (u_char) rx_maxReceiveWindow) || (offset > call->rwind)) { + if ((offset > (u_char) rx_maxReceiveWindow) || (offset > call->rwind)) { #ifndef RX_ENABLE_TSFPQ - if (!optionalPacket) - rxi_FreePacket(p); + if (!optionalPacket) + rxi_FreePacket(p); #endif - rxi_CallError(call, RX_CALL_DEAD); - return optionalPacket; + rxi_CallError(call, RX_CALL_DEAD); + return optionalPacket; + } } } -- 2.39.5