* set the ack bits in the packets and have rxi_Start remove the packets
* when it's done transmitting.
*/
- if (!tp->acked) {
+ if (!(tp->flags & RX_PKTFLAG_ACKED)) {
newAckCount++;
}
if (call->flags & RX_CALL_TQ_BUSY) {
#ifdef RX_ENABLE_LOCKS
- tp->acked = 1;
+ tp->flags |= RX_PKTFLAG_ACKED;
call->flags |= RX_CALL_TQ_SOME_ACKED;
#else /* RX_ENABLE_LOCKS */
break;
* out of sequence. */
if (tp->header.seq < first) {
/* Implicit ack information */
- if (!tp->acked) {
+ if (!(tp->flags & RX_PKTFLAG_ACKED)) {
newAckCount++;
}
- tp->acked = 1;
+ tp->flags |= RX_PKTFLAG_ACKED;
}
else if (tp->header.seq < first + nAcks) {
/* Explicit ack information: set it in the packet appropriately */
if (ap->acks[tp->header.seq - first] == RX_ACK_TYPE_ACK) {
- if (!tp->acked) {
+ if (!(tp->flags & RX_PKTFLAG_ACKED)) {
newAckCount++;
- tp->acked = 1;
+ tp->flags |= RX_PKTFLAG_ACKED;
}
if (missing) {
nNacked++;
call->nSoftAcked++;
}
} else {
- tp->acked = 0;
+ tp->flags &= ~RX_PKTFLAG_ACKED;
missing = 1;
}
}
else {
- tp->acked = 0;
+ tp->flags &= ~RX_PKTFLAG_ACKED;
missing = 1;
}
* ie, this should readjust the retransmit timer for all outstanding
* packets... So we don't just retransmit when we should know better*/
- if (!tp->acked && !clock_IsZero(&tp->retryTime)) {
+ if (!(tp->flags & RX_PKTFLAG_ACKED) && !clock_IsZero(&tp->retryTime)) {
tp->retryTime = tp->timeSent;
clock_Add(&tp->retryTime, &peer->timeout);
/* shift by eight because one quarter-sec ~ 256 milliseconds */
* so we will retransmit as soon as the window permits*/
for(acked = 0, queue_ScanBackwards(&call->tq, tp, nxp, rx_packet)) {
if (acked) {
- if (!tp->acked) {
+ if (!(tp->flags & RX_PKTFLAG_ACKED)) {
clock_Zero(&tp->retryTime);
}
- } else if (tp->acked) {
+ } else if (tp->flags & RX_PKTFLAG_ACKED) {
acked = 1;
}
}
for (queue_Scan(&call->tq, p, tp, rx_packet)) {
if (!p)
break;
- p->acked = 1;
+ p->flags |= RX_PKTFLAG_ACKED;
someAcked = 1;
}
if (someAcked) {
for (queue_Scan(&call->tq, p, tp, rx_packet)) {
if (!p)
break;
- p->acked = 1;
+ p->flags |= RX_PKTFLAG_ACKED;
someAcked = 1;
}
if (someAcked) {
/* Does the current packet force us to flush the current list? */
if (cnt > 0
&& (list[i]->header.serial
- || list[i]->acked
+ || (list[i]->flags & RX_PKTFLAG_ACKED)
|| list[i]->length > RX_JUMBOBUFFERSIZE)) {
if (lastCnt > 0) {
rxi_SendList(call, lastP, lastCnt, istack, 1, now, retryTime, resending);
}
/* Add the current packet to the list if it hasn't been acked.
* Otherwise adjust the list pointer to skip the current packet. */
- if (!list[i]->acked) {
+ if (!(list[i]->flags & RX_PKTFLAG_ACKED)) {
cnt++;
/* Do we need to flush the list? */
if (cnt >= (int)peer->maxDgramPackets
* an acked packet. Since we always send retransmissions
* in a separate packet, we only need to check the first
* packet in the list */
- if (cnt > 0 && !listP[0]->acked) {
+ if (cnt > 0 && !(listP[0]->flags & RX_PKTFLAG_ACKED)) {
morePackets = 1;
}
if (lastCnt > 0) {
* than recovery rates.
*/
for(queue_Scan(&call->tq, p, nxp, rx_packet)) {
- if (!p->acked) {
+ if (!(p->flags & RX_PKTFLAG_ACKED)) {
clock_Zero(&p->retryTime);
}
}
/* Only send one packet during fast recovery */
break;
}
- if ((p->header.flags == RX_FREE_PACKET) ||
+ if ((p->flags & RX_PKTFLAG_FREE) ||
(!queue_IsEnd(&call->tq, nxp)
- && (nxp->header.flags == RX_FREE_PACKET)) ||
+ && (nxp->flags & RX_PKTFLAG_FREE)) ||
(p == (struct rx_packet *)&rx_freePacketQueue) ||
(nxp == (struct rx_packet *)&rx_freePacketQueue)) {
osi_Panic("rxi_Start: xmit queue clobbered");
}
- if (p->acked) {
+ if (p->flags & RX_PKTFLAG_ACKED) {
MUTEX_ENTER(&rx_stats_mutex);
rx_stats.ignoreAckedPacket++;
MUTEX_EXIT(&rx_stats_mutex);
* the transmit queue.
*/
for (missing = 0, queue_Scan(&call->tq, p, nxp, rx_packet)) {
- if (p->header.seq < call->tfirst && p->acked) {
+ if (p->header.seq < call->tfirst && (p->flags & RX_PKTFLAG_ACKED)) {
queue_Remove(p);
rxi_FreePacket(p);
}
break;
}
- if (!p->acked && !clock_IsZero(&p->retryTime)) {
+ if (!(p->flags & RX_PKTFLAG_ACKED) && !clock_IsZero(&p->retryTime)) {
haveEvent = 1;
retryTime = p->retryTime;
break;
rx_nFreePackets--;
c = queue_First(&rx_freePacketQueue, rx_packet);
queue_Remove(c);
- if (c->header.flags != RX_FREE_PACKET)
+ if (!(c->flags & RX_PKTFLAG_FREE))
osi_Panic("rxi_AllocPacket: packet not free\n");
+ c->flags &= ~RX_PKTFLAG_FREE;
c->header.flags = 0;
#ifdef KERNEL
p->wirevec[0].iov_len = RX_HEADER_SIZE;
p->wirevec[1].iov_base = (char *) (p->localdata);
p->wirevec[1].iov_len = RX_FIRSTBUFFERSIZE;
- p->header.flags = RX_FREE_PACKET;
+ p->flags |= RX_PKTFLAG_FREE;
p->niovecs = 2;
queue_Append(&rx_freePacketQueue, p);
p->wirevec[0].iov_len = RX_HEADER_SIZE;
p->wirevec[1].iov_base = (char *) (p->localdata);
p->wirevec[1].iov_len = RX_FIRSTBUFFERSIZE;
- p->header.flags = RX_FREE_PACKET;
+ p->flags |= RX_PKTFLAG_FREE;
p->niovecs = 2;
queue_Append(&rx_freePacketQueue, p);
{
dpf(("Free %x\n", p));
- if (p->header.flags & RX_FREE_PACKET)
+ if (p->flags & RX_PKTFLAG_FREE)
osi_Panic("rxi_FreePacketNoLock: packet already free\n");
rx_nFreePackets++;
- p->header.flags = RX_FREE_PACKET;
+ p->flags |= RX_PKTFLAG_FREE;
queue_Append(&rx_freePacketQueue, p);
}
rx_nFreePackets--;
p = queue_First(&rx_freePacketQueue, rx_packet);
- if (p->header.flags != RX_FREE_PACKET)
+ if (!(p->flags & RX_PKTFLAG_FREE))
osi_Panic("rxi_AllocPacket: packet not free\n");
dpf(("Alloc %x, class %d\n", p, class));
queue_Remove(p);
+ p->flags &= ~RX_PKTFLAG_FREE;
p->header.flags = 0;
/* have to do this here because rx_FlushWrite fiddles with the iovs in
int i, j;
ssize_t len; /* len must be a signed type; it can go negative */
- p->acked = 0;
+ p->flags &= ~RX_PKTFLAG_ACKED;
p->header.cid = (conn->cid | call->channel);
p->header.serviceId = conn->serviceId;
p->header.securityIndex = conn->securityIndex;
* the receiver should be greater than
* this one, rather than a resend of an
* earlier sequence number */
-#define RX_FREE_PACKET 16 /* Unallocated to a call */
#define RX_SLOW_START_OK 32 /* Set this flag in an ack packet to
* inform the sender that slow start is
* supported by the receiver. */
#define RX_PRESET_FLAGS (RX_CLIENT_INITIATED | RX_LAST_PACKET)
+/*
+ * Flags for the packet structure itself, housekeeping for the
+ * most part. These live in rx_packet->flags.
+ */
+#define RX_PKTFLAG_ACKED 0x01
+#define RX_PKTFLAG_FREE 0x02
+
+
/* The rx part of the header of a packet, in host form */
struct rx_header {
afs_uint32 epoch; /* Start time of client process */
unsigned int niovecs;
struct iovec wirevec[RX_MAXWVECS+1]; /* the new form of the packet */
- u_char acked; /* This packet has been *tentatively* acknowledged */
+ u_char flags; /* Flags for local state of this packet */
u_char backoff; /* for multiple re-sends */
u_short length; /* Data length */
/* NT port relies on the fact that the next two are physically adjacent.