org.filesys.oncrpc.RpcPacket Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jfileserver Show documentation
Show all versions of jfileserver Show documentation
Java file server with SMB, FTP/FTPS and NFS support, virtual filesystems, database filesystems
The newest version!
/*
* Copyright (C) 2006-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see .
*/
package org.filesys.oncrpc;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import org.filesys.util.DataPacker;
import org.filesys.util.UTF8Normalizer;
/**
* ONC/RPC Request/Response Packet Class
*
* @author gkspencer
*/
public class RpcPacket {
// Constants
//
// Default buffer size to allocate
private static final int DefaultBufferSize = 8192;
// Fragment header length
public static final int FragHeaderLen = 4;
// Fixed packet lengths
public static final int ResponseMismatchLen = 24;
public static final int ResponseAuthFailLen = 20;
// UTF-8 string normalizer
private static UTF8Normalizer _utf8Normalizer = new UTF8Normalizer();
// RPC data buffer
private byte[] m_buffer;
private int m_offset;
// Current buffer pack/unpack position and end of buffer position
private int m_pos;
private int m_endPos;
// Callers address, port and protocol
private InetAddress m_clientAddr;
private int m_clientPort;
private Rpc.ProtocolId m_protocol;
// RPC packet handler interface used to send an RPC response
private RpcPacketHandler m_pktHandler;
// Packet pool that owns this packet, if allocated from a pool
private RpcPacketPool m_ownerPool;
// Set the lease time for packets allocated from the pool
private long m_leaseTime;
// Associated RPC packet
private RpcPacket m_assocPacket;
/**
* Default constructor
*/
public RpcPacket() {
// Allocate the RPC buffer
m_buffer = new byte[DefaultBufferSize];
m_offset = FragHeaderLen;
m_pos = FragHeaderLen;
m_endPos = m_buffer.length;
}
/**
* Class constructor
*
* @param len int
*/
public RpcPacket(int len) {
// Allocate the RPC buffer
m_buffer = new byte[len + FragHeaderLen];
m_offset = FragHeaderLen;
m_pos = FragHeaderLen;
m_endPos = m_buffer.length;
}
/**
* Class constructor
*
* @param len int
* @param owner RpcPacketPool
*/
protected RpcPacket(int len, RpcPacketPool owner) {
this(len);
// Set the owner
setOwnerPacketPool(owner);
}
/**
* Class constructor
*
* @param buf byte[]
*/
public RpcPacket(byte[] buf) {
m_buffer = buf;
m_offset = FragHeaderLen;
m_pos = FragHeaderLen;
m_endPos = buf.length;
}
/**
* Class constructor
*
* @param buf byte[]
* @param offset int
* @param len int
*/
public RpcPacket(byte[] buf, int offset, int len) {
m_buffer = buf;
m_offset = offset;
m_pos = offset;
m_endPos = offset + len;
}
/**
* Determine if the packet handler is valid
*
* @return boolean
*/
public final boolean hasPacketHandler() {
return m_pktHandler != null ? true : false;
}
/**
* Return the packet handler interface used to send/receive a packet
*
* @return RpcPacketHandler
*/
public final RpcPacketHandler getPacketHandler() {
return m_pktHandler;
}
/**
* Detemrine if the packet is allocated from a packet pool
*
* @return boolean
*/
public final boolean isAllocatedFromPool() {
return m_ownerPool != null ? true : false;
}
/**
* Return the packet pool that owns this packet
*
* @return RpcPacketPool
*/
public final RpcPacketPool getOwnerPacketPool() {
return m_ownerPool;
}
/**
* Determine if the client address has been set
*
* @return boolean
*/
public final boolean hasClientAddress() {
return m_clientAddr != null ? true : false;
}
/**
* Return the client network address
*
* @return InetAddress
*/
public final InetAddress getClientAddress() {
return m_clientAddr;
}
/**
* Return the client port
*
* @return int
*/
public final int getClientPort() {
return m_clientPort;
}
/**
* Return the client protocol
*
* @return Rpc.ProtocolId
*/
public final Rpc.ProtocolId getClientProtocol() {
return m_protocol;
}
/**
* Return the client details as a string
*
* @return String
*/
public final String getClientDetails() {
if (hasClientAddress() == false)
return "";
StringBuffer str = new StringBuffer(32);
str.append(getClientProtocol().name());
str.append(getClientAddress().getHostAddress());
str.append(":");
str.append(getClientPort());
return str.toString();
}
/**
* Check if the packet has a lease
*
* @return boolean
*/
public final boolean hasLeaseTime() {
return m_leaseTime != 0 ? true : false;
}
/**
* Return the packet lease time
*
* @return long
*/
public final long getLeaseTime() {
return m_leaseTime;
}
/**
* Clear the lease time
*/
public final void clearLeaseTime() {
m_leaseTime = 0L;
}
/**
* Set the packet lease time
*
* @param tmo long
*/
public final void setLeaseTime( long tmo) {
m_leaseTime = tmo;
}
/**
* Check if there is an associated RPC packet
*
* @return boolean
*/
public final boolean hasAssociatedPacket() {
return m_assocPacket != null ? true : false;
}
/**
* Return the associated packet
*
* @return RpcPacket
*/
public final RpcPacket getAssociatedPacket() {
return m_assocPacket;
}
/**
* Set the associated RPC packet
*
* @param assocPkt RpcPacket
*/
public final void setAssociatedPacket(RpcPacket assocPkt) {
m_assocPacket = assocPkt;
}
/**
* Return the current buffer position
*
* @return int
*/
public final int getPosition() {
return m_pos;
}
/**
* Return the buffer
*
* @return byte[]
*/
public final byte[] getBuffer() {
return m_buffer;
}
/**
* Return the length of the request header
*
* @return int
*/
public final int getRequestHeaderLength() {
int hdrLen = 28 + 8 + 8;
hdrLen += getCredentialsLength();
hdrLen += getVerifierLength();
return hdrLen;
}
/**
* Return the available buffer size
*
* @return int
*/
public final int getAvailableLength() {
return m_buffer.length - m_pos;
}
/**
* Return the used buffer length
*
* @return int
*/
public final int getLength() {
return m_endPos - m_offset;
}
/**
* Return the RPC + fragment header length
*
* @return int
*/
public final int getTxLength() {
if (m_offset == 0)
return m_endPos;
else
return (m_endPos - m_offset) + FragHeaderLen;
}
/**
* Return the start of data offset
*
* @return int
*/
public final int getOffset() {
return m_offset;
}
/**
* Return the message type
*
* @return Rpc.MessageType
*/
public final Rpc.MessageType getMessageType() {
return Rpc.MessageType.fromInt(DataPacker.getInt(m_buffer, m_offset + 4));
}
/**
* Return the RPC version
*
* @return int
*/
public final int getRpcVersion() {
return DataPacker.getInt(m_buffer, m_offset + 8);
}
/**
* Return the program id
*
* @return int
*/
public final int getProgramId() {
return DataPacker.getInt(m_buffer, m_offset + 12);
}
/**
* Return the program version
*
* @return int
*/
public final int getProgramVersion() {
return DataPacker.getInt(m_buffer, m_offset + 16);
}
/**
* Return the procedure id
*
* @return int
*/
public final int getProcedureId() {
return DataPacker.getInt(m_buffer, m_offset + 20);
}
/**
* Return the credentials type
*
* @return AuthType
*/
public final AuthType getCredentialsType() {
return AuthType.fromInt(DataPacker.getInt(m_buffer, m_offset + 24));
}
/**
* Return the credentials length
*
* @return int
*/
public final int getCredentialsLength() {
return DataPacker.getInt(m_buffer, m_offset + 28);
}
/**
* Return the verifier type
*
* @return int
*/
public final int getVerifierType() {
return DataPacker.getInt(m_buffer, m_offset + getCredentialsLength() + 32);
}
/**
* Return the verifier length
*
* @return int
*/
public final int getVerifierLength() {
return DataPacker.getInt(m_buffer, m_offset + getCredentialsLength() + 36);
}
/**
* Return the buffer offset to the verifier
*
* @return int
*/
public final int getVerifierOffset() {
return m_offset + getCredentialsLength() + 40;
}
/**
* Return the procedure specific parameters offset
*
* @return int
*/
public final int getProcedureParameterOffset() {
return m_offset + getCredentialsLength() + getVerifierLength() + 40;
}
/**
* Return the procedure parameters length
*
* @return int
*/
public final int getProcedureParameterLength() {
return m_endPos - getProcedureParameterOffset();
}
/**
* Return the XID
*
* @return int
*/
public final int getXID() {
return DataPacker.getInt(m_buffer, m_offset);
}
/**
* Check if the response has a success status
*
* @return boolean
*/
public final boolean hasSuccessStatus() {
return getAcceptStatus() == Rpc.AcceptSts.Success ? true : false;
}
/**
* Return the reply state
*
* @return Rpc.CallStatus
*/
public final Rpc.CallStatus getReplyState() {
return Rpc.CallStatus.fromInt(DataPacker.getInt(m_buffer, 8));
}
/**
* Return the reject reply status
*
* @return Rpc.RejectSts
*/
public final Rpc.RejectSts getRejectStatus() {
return Rpc.RejectSts.fromInt(DataPacker.getInt(m_buffer, 12));
}
/**
* Return the version mismatch low version
*
* @return int
*/
public final int getMismatchVersionLow() {
return DataPacker.getInt(m_buffer, 16);
}
/**
* Return the version mismatch high version
*
* @return int
*/
public final int getMismatchVersionHigh() {
return DataPacker.getInt(m_buffer, 20);
}
/**
* Return the authentication failure status
*
* @return int
*/
public final int getAuthFailStatus() {
return DataPacker.getInt(m_buffer, 16);
}
/**
* Return the accept status for the RPC response
*
* @return Rpc.AcceptSts
*/
public final Rpc.AcceptSts getAcceptStatus() {
int pos = DataPacker.getInt(m_buffer, 16) + 20;
return Rpc.AcceptSts.fromInt(DataPacker.getInt(m_buffer, pos));
}
/**
* Align the buffer position on a longword/32bit boundary
*/
protected final void alignPosition() {
// Align the buffer position on the required boundary
m_pos = (m_pos + 3) & 0xFFFFFFFC;
}
/**
* Pack a byte value
*
* @param bval int
*/
public final void packByte(int bval) {
m_buffer[m_pos++] = (byte) (bval & 0xFF);
}
/**
* Pack nulls
*
* @param len int
*/
public final void packNulls(int len) {
for (int i = 0; i < len; i++)
m_buffer[m_pos++] = (byte) 0;
}
/**
* Pack an integer value
*
* @param ival int
*/
public final void packInt(int ival) {
DataPacker.putInt(ival, m_buffer, m_pos);
m_pos += 4;
}
/**
* Pack a long value
*
* @param lval long
*/
public final void packLong(long lval) {
DataPacker.putLong(lval, m_buffer, m_pos);
m_pos += 8;
}
/**
* Pack a byte array with a length
*
* @param buf byte[]
*/
public final void packByteArrayWithLength(byte[] buf) {
DataPacker.putInt(buf.length, m_buffer, m_pos);
m_pos += 4;
System.arraycopy(buf, 0, m_buffer, m_pos, buf.length);
m_pos += buf.length;
alignPosition();
}
/**
* Pack a byte array
*
* @param buf byte[]
*/
public final void packByteArray(byte[] buf) {
System.arraycopy(buf, 0, m_buffer, m_pos, buf.length);
m_pos += buf.length;
alignPosition();
}
/**
* Pack an integer array
*
* @param iarray int[]
*/
public final void packIntArrayWithLength(int[] iarray) {
DataPacker.putInt(iarray.length, m_buffer, m_pos);
m_pos += 4;
for (int i = 0; i < iarray.length; i++) {
DataPacker.putInt(iarray[i], m_buffer, m_pos);
m_pos += 4;
}
}
/**
* Pack a string
*
* @param str String
*/
public final void packString(String str) {
DataPacker.putInt(str != null ? str.getBytes().length : 0, m_buffer, m_pos);
m_pos += 4;
if (str != null) {
m_pos = DataPacker.putString(str, m_buffer, m_pos, false);
alignPosition();
}
}
/**
* Pack a UTF-8 string
*
* @param str String
*/
public final void packUTF8String(String str) {
byte[] strByts = null;
try {
if (str != null)
strByts = str.getBytes("UTF-8");
}
catch (Exception ex) {
}
DataPacker.putInt(strByts != null ? strByts.length : 0, m_buffer, m_pos);
m_pos += 4;
if (str != null) {
System.arraycopy(strByts, 0, m_buffer, m_pos, strByts.length);
m_pos += strByts.length;
alignPosition();
}
}
/**
* Pack a port mapping structure
*
* @param portMap PortMapping
*/
public final void packPortMapping(PortMapping portMap) {
DataPacker.putInt(portMap.getProgramId(), m_buffer, m_pos);
DataPacker.putInt(portMap.getVersionId(), m_buffer, m_pos + 4);
DataPacker.putInt(portMap.getProtocol().intValue(), m_buffer, m_pos + 8);
DataPacker.putInt(portMap.getPort(), m_buffer, m_pos + 12);
m_pos += 16;
}
/**
* Unpack an integer value
*
* @return int
*/
public final int unpackInt() {
int val = DataPacker.getInt(m_buffer, m_pos);
m_pos += 4;
return val;
}
/**
* Unpack a long value
*
* @return long
*/
public final long unpackLong() {
long val = DataPacker.getLong(m_buffer, m_pos);
m_pos += 8;
return val;
}
/**
* Unpack a string
*
* @return String
*/
public final String unpackString() {
int len = unpackInt();
String str = "";
if (len > 0) {
str = DataPacker.getString(m_buffer, m_pos, len);
m_pos += len;
alignPosition();
}
return str;
}
/**
* Unpack a UTF-8 string
*
* @return String
*/
public final String unpackUTF8String() {
int len = unpackInt();
String str = "";
if (len > 0) {
// Check for any bytes with the high bit set, run the string through
// the UTF-8 normalizer if any are found
boolean utf8 = false;
int idx = 0;
while (utf8 == false && idx < len) {
if (((int) m_buffer[m_pos + idx] & 0x80) != 0)
utf8 = true;
else
idx++;
}
// Normalize the UTF-8 bytes
if (utf8 == true) {
// Create a UTF8 string and normalize
try {
str = new String(m_buffer, m_pos, len, "UTF8");
str = _utf8Normalizer.normalize(str);
}
catch (UnsupportedEncodingException ex) {
}
} else {
// Unpack the bytes into a string
str = DataPacker.getString(m_buffer, m_pos, len);
}
// Update the buffer position
m_pos += len;
alignPosition();
}
return str;
}
/**
* Unpack a byte array with a length
*
* @param buf byte[]
*/
public final void unpackByteArrayWithLength(byte[] buf) {
int len = DataPacker.getInt(m_buffer, m_pos);
m_pos += 4;
if (len > 0) {
if (len > buf.length)
System.arraycopy(m_buffer, m_pos, buf, 0, buf.length);
else
System.arraycopy(m_buffer, m_pos, buf, 0, len);
m_pos += len;
}
alignPosition();
}
/**
* Unpack a byte array, using the buffer length
*
* @param buf byte[]
*/
public final void unpackByteArray(byte[] buf) {
System.arraycopy(m_buffer, m_pos, buf, 0, buf.length);
m_pos += buf.length;
alignPosition();
}
/**
* Unpack an integer array, using the buffer length
*
* @param buf int[]
*/
public final void unpackIntArray(int[] buf) {
for (int i = 0; i < buf.length; i++)
buf[i] = unpackInt();
}
/**
* Position the read pointer at the credentials data
*/
public final void positionAtCredentialsData() {
m_pos = m_offset + 32;
}
/**
* Position the read pointer at the verifier data
*/
public final void positionAtVerifierData() {
m_pos = getVerifierOffset();
}
/**
* Position the read pointer at the procedure specific parameters
*/
public final void positionAtParameters() {
m_pos = getProcedureParameterOffset();
}
/**
* Skip a number of bytes in the buffer, rounded to the next int boundary
*
* @param cnt int
*/
public final void skipBytes(int cnt) {
m_pos += (cnt + 3) & 0xFFFC;
}
/**
* Set the client details
*
* @param addr InetAddress
* @param port int
* @param protocol Rpc.ProtocolId
*/
public final void setClientDetails(InetAddress addr, int port, Rpc.ProtocolId protocol) {
m_clientAddr = addr;
m_clientPort = port;
m_protocol = protocol;
}
/**
* Reset the buffer details
*
* @param buf byte[]
* @param offset int
* @param len int
*/
public final void setBuffer(byte[] buf, int offset, int len) {
m_buffer = buf;
m_offset = offset;
m_pos = offset;
m_endPos = offset + len;
}
/**
* Reset the buffer details
*
* @param offset int
* @param len int
*/
public final void setBuffer(int offset, int len) {
m_offset = offset;
m_pos = offset;
m_endPos = offset + len;
}
/**
* Set the used buffer length
*
* @param len int
*/
public final void setLength(int len) {
m_endPos = len + m_offset;
// Set the fragment header, if the offset is non-zero
if (m_offset == FragHeaderLen)
DataPacker.putInt(getLength() + Rpc.LastFragment, m_buffer, 0);
}
/**
* Set the used buffer length
*/
public final void setLength() {
m_endPos = m_pos;
// Set the fragment header, if the offset is non-zero
if (m_offset == FragHeaderLen)
DataPacker.putInt(getLength() + Rpc.LastFragment, m_buffer, 0);
}
/**
* Set the buffer position
*
* @param pos int
*/
public final void setPosition(int pos) {
m_pos = pos;
}
/**
* Set the message type
*
* @param msgType Rpc.MessageType
*/
public final void setMessageType(Rpc.MessageType msgType) {
DataPacker.putInt(msgType.intValue(), m_buffer, m_offset + 4);
}
/**
* Set the RPC version
*
* @param rpcVer int
*/
public final void setRpcVersion(int rpcVer) {
DataPacker.putInt(rpcVer, m_buffer, m_offset + 8);
}
/**
* Set the program id
*
* @param progId int
*/
public final void setProgramId(int progId) {
DataPacker.putInt(progId, m_buffer, m_offset + 12);
}
/**
* Set the program version
*
* @param progVer int
*/
public final void setProgramVersion(int progVer) {
DataPacker.putInt(progVer, m_buffer, m_offset + 16);
}
/**
* Set the procedure id
*
* @param procId int
*/
public final void setProcedureId(int procId) {
DataPacker.putInt(procId, m_buffer, m_offset + 20);
}
/**
* Set the credentials type
*
* @param credtype int
*/
public final void setCredentialsType(int credtype) {
DataPacker.putInt(credtype, m_buffer, m_offset + 24);
}
/**
* Set the credentials length
*
* @param credlen int
*/
public final void setCredentialsLength(int credlen) {
DataPacker.putInt(credlen, m_buffer, m_offset + 28);
}
/**
* Set the reply state
*
* @param replySts Rpc.CallStatus
*/
public final void setReplyState(Rpc.CallStatus replySts) {
DataPacker.putInt(replySts.intValue(), m_buffer, m_offset + 8);
}
/**
* Set the reject status
*
* @param rejSts Rpc.RejectSts
*/
public final void setRejectStatus(Rpc.RejectSts rejSts) {
DataPacker.putInt(rejSts.intValue(), m_buffer, m_offset + 8);
}
/**
* Set the RPC mismatch values
*
* @param rpcLow int
* @param rpcHigh int
*/
public final void setRpcMismatch(int rpcLow, int rpcHigh) {
DataPacker.putInt(rpcLow, m_buffer, m_offset + 12);
DataPacker.putInt(rpcHigh, m_buffer, m_offset + 16);
}
/**
* Set the authentication failure status
*
* @param authSts Rpc.AuthSts
*/
public final void setAuthFailStatus(Rpc.AuthSts authSts) {
DataPacker.putInt(authSts.intValue(), m_buffer, m_offset + 8);
}
/**
* Set the verifier type
*
* @param verftype int
*/
public final void setVerifierType(int verftype) {
DataPacker.putInt(verftype, m_buffer, m_offset + getCredentialsLength() + 32);
}
/**
* Set the verifier length
*
* @param verflen int
*/
public final void setVerifierLength(int verflen) {
DataPacker.putInt(verflen, m_buffer, m_offset + getCredentialsLength() + 36);
}
/**
* Set the associated packet handler interface for the packet
*
* @param pktHandler RpcPacketHandler
*/
public final void setPacketHandler(RpcPacketHandler pktHandler) {
m_pktHandler = pktHandler;
}
/**
* Set the XID
*
* @param xid int
*/
public final void setXID(int xid) {
DataPacker.putInt(xid, m_buffer, m_offset);
}
/**
* Set the owner packet pool, if the packet was allocated from a pool
*
* @param pool RpcPacketPool
*/
protected final void setOwnerPacketPool(RpcPacketPool pool) {
m_ownerPool = pool;
}
/**
* Build an RPC request header, and set the buffer pointer ready to stream data into the parameter
* area of the request
*
* @param progId int
* @param verId int
* @param procId int
* @param credType int
* @param cred byte[]
* @param verfType int
* @param verf byte[]
*/
public final void buildRequestHeader(int progId, int verId, int procId, int credType, byte[] cred,
int verfType, byte[] verf) {
// Generate an id for the request
setXID((int) (System.currentTimeMillis() & 0xFFFFFFFFL));
// Set the message type and RPC version (always version 2)
setMessageType(Rpc.MessageType.Call);
setRpcVersion(Rpc.RpcVersion);
// Set the request details
setProgramId(progId);
setProgramVersion(verId);
setProcedureId(procId);
// Set the credentials type, length and value
setCredentialsType(credType);
setCredentialsLength(cred != null ? cred.length : 0);
if (cred != null)
System.arraycopy(cred, 0, m_buffer, m_offset + 32, cred.length);
// Set the verifier type, length and value
setVerifierType(verfType);
setVerifierLength(verf != null ? verf.length : 0);
if (verf != null) {
int pos = getVerifierOffset();
System.arraycopy(verf, 0, m_buffer, pos, verf.length);
}
// Position the buffer pointer at the request parameter area
positionAtParameters();
}
/**
* Build a response header for a valid RPC response and set the buffer pointer ready to stream data
* into the parameter area of the response.
*/
public final void buildResponseHeader() {
setMessageType(Rpc.MessageType.Reply);
setReplyState(Rpc.CallStatus.Accepted);
// Copy the verifier from the request
DataPacker.putInt(getVerifierType(), m_buffer, m_offset + 12);
int verfLen = getVerifierLength();
DataPacker.putInt(verfLen, m_buffer, m_offset + 16);
if (verfLen > 0)
System.arraycopy(m_buffer, getVerifierOffset(), m_buffer, m_offset + 20, verfLen);
// Indicate a success status
DataPacker.putInt(Rpc.AcceptSts.Success.intValue(), m_buffer, m_offset + 20 + verfLen);
// Set the buffer pointer for streaming the response parameters
m_pos = m_offset + 24 + verfLen;
setLength();
}
/**
* Build an error response packet where the RPC has been accepted but returns a status code in the parameter area.
*
* @param stsCode int
*/
public final void buildErrorResponse(int stsCode) {
// Check if the RPC is a request or reply
boolean isReply = getMessageType() == Rpc.MessageType.Reply;
// Set the reply header
setMessageType(Rpc.MessageType.Reply);
setReplyState(Rpc.CallStatus.Accepted);
// Copy the verifier from the request
int verfLen = 0;
if (isReply == false) {
DataPacker.putInt(getVerifierType(), m_buffer, m_offset + 12);
verfLen = getVerifierLength();
DataPacker.putInt(verfLen, m_buffer, m_offset + 16);
if (verfLen > 0)
System.arraycopy(m_buffer, getVerifierOffset(), m_buffer, m_offset + 20, verfLen);
} else {
// Get the verifier length from the reply
verfLen = DataPacker.getInt(m_buffer, m_offset + 16);
}
// Indicate a success status
DataPacker.putInt(Rpc.AcceptSts.Success.intValue(), m_buffer, m_offset + 20 + verfLen);
// Set the buffer pointer for streaming the response parameters
m_pos = m_offset + 24 + verfLen;
// Pack the service status code
DataPacker.putInt(stsCode, m_buffer, m_pos);
m_pos += 4;
setLength();
}
/**
* Build an RPC version mismatch response
*/
public final void buildRpcMismatchResponse() {
setMessageType(Rpc.MessageType.Reply);
setReplyState(Rpc.CallStatus.Denied);
setRejectStatus(Rpc.RejectSts.RpcMismatch);
setRpcMismatch(Rpc.RpcVersion, Rpc.RpcVersion);
setLength(ResponseMismatchLen);
}
/**
* Build an RPC authentication failure response
*
* @param stsCode Rpc.AuthSts
*/
public final void buildAuthFailResponse(Rpc.AuthSts stsCode) {
setMessageType(Rpc.MessageType.Reply);
setReplyState(Rpc.CallStatus.Denied);
setRejectStatus(Rpc.RejectSts.AuthError);
setAuthFailStatus(stsCode);
setLength(ResponseAuthFailLen);
}
/**
* Build an RPC accept error response
*
* @param stsCode Rpc.AcceptSts
*/
public final void buildAcceptErrorResponse(Rpc.AcceptSts stsCode) {
setMessageType(Rpc.MessageType.Reply);
setReplyState(Rpc.CallStatus.Accepted);
// Copy the verifier from the request
DataPacker.putInt(getVerifierType(), m_buffer, m_offset + 12);
int verfLen = getVerifierLength();
DataPacker.putInt(verfLen, m_buffer, m_offset + 16);
if (verfLen > 0)
System.arraycopy(m_buffer, getVerifierOffset(), m_buffer, m_offset + 20, verfLen);
// Pack the status code
DataPacker.putInt(stsCode.intValue(), m_buffer, m_offset + 20 + verfLen);
// Set the response length
setLength(m_offset + 24 + verfLen);
}
/**
* Build a program mismatch error response
*
* @param verLow int
* @param verHigh int
*/
public final void buildProgramMismatchResponse(int verLow, int verHigh) {
setMessageType(Rpc.MessageType.Reply);
setReplyState(Rpc.CallStatus.Accepted);
// Copy the verifier from the request
DataPacker.putInt(getVerifierType(), m_buffer, m_offset + 12);
int verfLen = getVerifierLength();
DataPacker.putInt(verfLen, m_buffer, m_offset + 16);
if (verfLen > 0)
System.arraycopy(m_buffer, getVerifierOffset(), m_buffer, m_offset + 20, verfLen);
// Pack the status code, and low/high version numbers
int pos = m_offset + 20 + verfLen;
DataPacker.putInt(Rpc.AcceptSts.ProgMismatch.intValue(), m_buffer, pos);
DataPacker.putInt(verLow, m_buffer, pos + 4);
DataPacker.putInt(verHigh, m_buffer, pos + 8);
// Set the response length
setLength(pos + 12);
}
/**
* Return the RPC packet as a string
*
* @return String
*/
public String toString() {
StringBuffer str = new StringBuffer(128);
// Dump the client details
str.append("[");
if (hasClientAddress()) {
str.append(getClientProtocol().name());
str.append(getClientAddress().getHostAddress());
str.append(":");
str.append(getClientPort());
} else
str.append("");
// Dump the call/response header
if (getMessageType() == Rpc.MessageType.Call) {
// Request packet
str.append("-Call,XID=0x");
str.append(Integer.toHexString(getXID()));
str.append(",RpcVer=");
str.append(getRpcVersion());
str.append(",ProgId=");
str.append(getProgramId());
str.append(",ProgVer=");
str.append(getProgramVersion());
str.append(",Proc=");
str.append(getProcedureId());
str.append(",CredType=");
str.append(getCredentialsType());
str.append(",CredLen=");
str.append(getCredentialsLength());
str.append(",VerfType");
str.append(getVerifierType());
str.append(",VerfLen=");
str.append(getVerifierLength());
str.append(",ParamLen=");
str.append(getProcedureParameterLength());
} else {
// Response packet
str.append("-Reply,XID=0x");
str.append(Integer.toHexString(getXID()));
if (getReplyState() == Rpc.CallStatus.Accepted) {
// Request accepted response
str.append(",Accepted");
} else {
// Request denied response
str.append(",Denied");
if (getRejectStatus() == Rpc.RejectSts.RpcMismatch) {
str.append(",RpcMismatch, Low=");
str.append(getMismatchVersionLow());
str.append("/High=");
str.append(getMismatchVersionHigh());
} else {
str.append(",AuthError, Status=");
;
str.append(getAuthFailStatus());
}
}
}
// Check if the packet is allocated from a pool
if (isAllocatedFromPool())
str.append(",Pool");
// Check if there is an associated packet
if ( hasAssociatedPacket())
str.append(",Assoc");
str.append("]");
// Return the string
return str.toString();
}
}