in src/filtration/rpc_filtrator.h [120:200]
inline bool validate_header(const MessageHeader* const msg, const size_t len)
{
switch(msg->type())
{
case MsgType::CALL:
{
auto call = static_cast<const CallHeader*>(msg);
if(RPCValidator::check(call))
{
BaseImpl::setMsgLen(len); // length of current RPC message
if(protocols::NFS3::Validator::check(call))
{
uint32_t proc{call->proc()};
if(API::ProcEnumNFS3::WRITE == proc) // truncate NFSv3 WRITE call message to NFSv3-RW-limit
{
BaseImpl::setToBeCopied(nfs3_rw_hdr_max < len ? nfs3_rw_hdr_max : len);
}
else
{
if(API::ProcEnumNFS3::READ == proc)
{
nfs3_read_match.insert(call->xid());
}
BaseImpl::setToBeCopied(len);
}
//TRACE("%p| MATCH RPC Call xid:%u len: %u procedure: %u", this, call->xid(), msg_len, call->proc());
}
else if(protocols::NFS4::Validator::check(call))
{
BaseImpl::setToBeCopied(len);
}
else
{
//* RPC call message must be read out ==> msg_len !=0
BaseImpl::setToBeCopied(0); // don't collect headers of unknown calls
//TRACE("Unknown RPC call of program: %u version: %u procedure: %u", call->prog(), call->vers(), call->proc());
}
return true;
}
else
{
return false; // isn't RPC Call, stream is corrupt
}
}
break;
case MsgType::REPLY:
{
auto reply = static_cast<const ReplyHeader*>(msg);
if(RPCValidator::check(reply))
{
BaseImpl::setMsgLen(len); // length of current RPC message
// Truncate NFSv3 READ reply message to NFSv3-RW-limit
//* Collect fully if reply received before matching call
if(nfs3_read_match.erase(reply->xid()) > 0)
{
BaseImpl::setToBeCopied(std::min(nfs3_rw_hdr_max, len));
}
else
{
BaseImpl::setToBeCopied(len); // length of current RPC message
}
//TRACE("%p| MATCH RPC Reply xid:%u len: %u", this, reply->xid(), msg_len);
return true;
}
else // isn't RPC reply, stream is corrupt
{
BaseImpl::setMsgLen(0);
BaseImpl::setToBeCopied(0);
return false;
}
}
break;
default:
{
//isn't RPC message
}
break;
}
return false;
}