From a9924ba433f81bfbfc2c0e726f2be06d460e4d56 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. Change-Id: Ibe0c76b4e92c5baa8801cfd12f961fabce223039 Reviewed-on: http://gerrit.openafs.org/5604 Reviewed-by: Derrick Brashear Tested-by: BuildBot --- 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 bb49d60d0..9ce55368c 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -5423,7 +5423,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 @@ -5531,37 +5531,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