queue_Remove(c);
if (!(c->flags & RX_PKTFLAG_FREE))
osi_Panic("rxi_AllocPacket: packet not free\n");
- c->flags &= ~RX_PKTFLAG_FREE;
+ c->flags = 0; /* clear RX_PKTFLAG_FREE, initialize the rest */
c->header.flags = 0;
#ifdef KERNEL
dpf(("Alloc %x, class %d\n", p, class));
queue_Remove(p);
- p->flags &= ~RX_PKTFLAG_FREE;
+ p->flags = 0; /* clear RX_PKTFLAG_FREE, initialize the rest */
p->header.flags = 0;
/* have to do this here because rx_FlushWrite fiddles with the iovs in
* our problems caused by the lack of a length field in the rx header.
* Use the extra buffer that follows the localdata in each packet
* structure. */
- savelen = p->wirevec[p->niovecs].iov_len;
- p->wirevec[p->niovecs].iov_len += RX_EXTRABUFFERSIZE;
+ savelen = p->wirevec[p->niovecs-1].iov_len;
+ p->wirevec[p->niovecs-1].iov_len += RX_EXTRABUFFERSIZE;
memset((char *)&msg, 0, sizeof(msg));
msg.msg_name = (char *) &from;
nbytes = rxi_Recvmsg(socket, &msg, 0);
/* restore the vec to its correct state */
- p->wirevec[p->niovecs].iov_len = savelen;
+ p->wirevec[p->niovecs-1].iov_len = savelen;
p->length = (nbytes - RX_HEADER_SIZE);
if ((nbytes > tlen) || (p->length & 0x8000)) { /* Bogus packet */
if (call) {
channel = call->channel;
callNumber = *call->callNumber;
- /* BUSY packets refer to the next call on this connection */
- if (type == RX_PACKET_TYPE_BUSY) {
- callNumber++;
- }
} else {
channel = 0;
callNumber = 0;
if (!p) {
p = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL);
if (!p) osi_Panic("rxi_SendSpecial failure");
+ } else if (type == RX_PACKET_TYPE_BUSY) {
+ /* BUSY packets refer to some subsequent call on this connection
+ * and we need to match the callNumber used by the other side. */
+ if (p->header.callNumber > callNumber) {
+ callNumber = p->header.callNumber;
+ }
}
if (nbytes != -1)
register afs_uint32 *buf = (afs_uint32*)(p->wirevec[0].iov_base); /* MTUXXX */
afs_uint32 temp;
- p->header.epoch = ntohl(*buf++);
- p->header.cid = ntohl(*buf++);
- p->header.callNumber = ntohl(*buf++);
- p->header.seq = ntohl(*buf++);
- p->header.serial = ntohl(*buf++);
- temp = ntohl(*buf++);
+ p->header.epoch = ntohl(*buf);
+ buf++;
+ p->header.cid = ntohl(*buf);
+ buf++;
+ p->header.callNumber = ntohl(*buf);
+ buf++;
+ p->header.seq = ntohl(*buf);
+ buf++;
+ p->header.serial = ntohl(*buf);
+ buf++;
+
+ temp = ntohl(*buf);
+ buf++;
+
/* C will truncate byte fields to bytes for me */
p->header.type = temp>>24;
p->header.flags = temp>>16;
p->header.userStatus = temp>>8;
p->header.securityIndex = temp>>0;
- temp = ntohl(*buf++);
+
+ temp = ntohl(*buf);
+ buf++;
+
p->header.serviceId = (temp&0xffff);
p->header.spare = temp>>16;
/* Note: top 16 bits of this last word are the security checksum */