nfs4: Reply to incorrect and CB_NULL callback requests

This commit is contained in:
Pawel Dziepak
2012-08-05 03:50:30 +02:00
parent 8019eaf184
commit feb15cc63c
11 changed files with 201 additions and 58 deletions
@@ -27,6 +27,7 @@ KernelAddon nfs4 :
RPCAuth.cpp RPCAuth.cpp
RPCCall.cpp RPCCall.cpp
RPCCallback.cpp RPCCallback.cpp
RPCCallbackReply.cpp
RPCCallbackRequest.cpp RPCCallbackRequest.cpp
RPCCallbackServer.cpp RPCCallbackServer.cpp
RPCReply.cpp RPCReply.cpp
@@ -16,6 +16,8 @@
#include <SupportDefs.h> #include <SupportDefs.h>
#include <util/kernel_cpp.h> #include <util/kernel_cpp.h>
#include "RPCDefs.h"
using namespace RPC; using namespace RPC;
@@ -14,11 +14,6 @@
namespace RPC { namespace RPC {
enum auth_flavour {
AUTH_NONE = 0,
AUTH_SYS = 1
};
class Auth { class Auth {
public: public:
inline const XDR::WriteStream& Stream() const; inline const XDR::WriteStream& Stream() const;
@@ -11,21 +11,11 @@
#include <util/kernel_cpp.h> #include <util/kernel_cpp.h>
#include "RPCDefs.h"
using namespace RPC; using namespace RPC;
enum {
CALL = 0
};
#define VERSION 2
enum {
PROGRAM_NFS = 100003
};
#define NFS_VERSION 4
Call::Call() Call::Call()
{ {
@@ -0,0 +1,49 @@
/*
* Copyright 2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, [email protected]
*/
#include "RPCCallbackReply.h"
#include <util/kernel_cpp.h>
#include "RPCDefs.h"
using namespace RPC;
CallbackReply::CallbackReply()
{
}
CallbackReply*
CallbackReply::Create(uint32 xid, AcceptStat rpcError)
{
CallbackReply* reply = new(std::nothrow) CallbackReply;
if (reply == NULL)
return NULL;
reply->fStream.AddUInt(xid);
reply->fStream.AddInt(REPLY);
reply->fStream.AddUInt(MSG_ACCEPTED);
reply->fStream.AddInt(AUTH_NONE);
reply->fStream.AddOpaque(NULL, 0);
reply->fStream.AddUInt(rpcError);
return reply;
}
CallbackReply::~CallbackReply()
{
}
@@ -0,0 +1,42 @@
/*
* Copyright 2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, [email protected]
*/
#ifndef RPCCALLBACKREPLY_H
#define RPCCALLBACKREPLY_H
#include "RPCDefs.h"
#include "XDR.h"
namespace RPC {
class CallbackReply {
public:
static CallbackReply* Create(uint32 xid,
AcceptStat rpcError = SUCCESS);
~CallbackReply();
inline XDR::WriteStream& Stream();
private:
CallbackReply();
XDR::WriteStream fStream;
};
inline XDR::WriteStream&
CallbackReply::Stream()
{
return fStream;
}
} // namespace RPC
#endif // RPCCALLBACKREPLY_H
@@ -12,26 +12,16 @@
#include <stdlib.h> #include <stdlib.h>
#include "NFS4Defs.h" #include "NFS4Defs.h"
#include "RPCDefs.h"
using namespace RPC; using namespace RPC;
enum {
CALL = 0
};
#define VERSION 2
enum {
PROGRAM_NFS_CB = 0x40000000
};
#define NFS_CB_VERSION 1
CallbackRequest::CallbackRequest(void *buffer, int size) CallbackRequest::CallbackRequest(void *buffer, int size)
: :
fError(B_BAD_VALUE), fError(B_BAD_VALUE),
fRPCError(GARBAGE_ARGS),
fStream(buffer, size), fStream(buffer, size),
fBuffer(buffer) fBuffer(buffer)
{ {
@@ -43,11 +33,15 @@ CallbackRequest::CallbackRequest(void *buffer, int size)
if (fStream.GetUInt() != VERSION) if (fStream.GetUInt() != VERSION)
return; return;
if (fStream.GetUInt() != PROGRAM_NFS_CB) if (fStream.GetUInt() != PROGRAM_NFS_CB) {
fRPCError = PROG_UNAVAIL;
return; return;
}
if (fStream.GetUInt() != NFS_CB_VERSION) if (fStream.GetUInt() != NFS_CB_VERSION) {
fRPCError = PROG_MISMATCH;
return; return;
}
fProcedure = fStream.GetUInt(); fProcedure = fStream.GetUInt();
@@ -60,9 +54,11 @@ CallbackRequest::CallbackRequest(void *buffer, int size)
return; return;
fID = fStream.GetUInt(); fID = fStream.GetUInt();
} } else if (fProcedure == CallbackProcNull) {
fRPCError = SUCCESS;
fError = B_OK; fError = B_OK;
} else
fRPCError = PROC_UNAVAIL;
} }
@@ -9,6 +9,7 @@
#define RPCCALLBACKREQUEST_H #define RPCCALLBACKREQUEST_H
#include "RPCDefs.h"
#include "XDR.h" #include "XDR.h"
@@ -25,6 +26,8 @@ public:
inline uint32 Procedure(); inline uint32 Procedure();
inline status_t Error(); inline status_t Error();
inline AcceptStat RPCError();
inline XDR::ReadStream& Stream(); inline XDR::ReadStream& Stream();
private: private:
@@ -34,6 +37,7 @@ private:
uint32 fProcedure; uint32 fProcedure;
status_t fError; status_t fError;
AcceptStat fRPCError;
XDR::ReadStream fStream; XDR::ReadStream fStream;
void* fBuffer; void* fBuffer;
@@ -68,6 +72,13 @@ CallbackRequest::Error()
} }
inline AcceptStat
CallbackRequest::RPCError()
{
return fRPCError;
}
inline XDR::ReadStream& inline XDR::ReadStream&
CallbackRequest::Stream() CallbackRequest::Stream()
{ {
@@ -11,6 +11,7 @@
#include "NFS4Defs.h" #include "NFS4Defs.h"
#include "RPCCallback.h" #include "RPCCallback.h"
#include "RPCCallbackReply.h"
#include "RPCCallbackRequest.h" #include "RPCCallbackRequest.h"
@@ -224,6 +225,7 @@ status_t
CallbackServer::ConnectionThread(ConnectionEntry* entry) CallbackServer::ConnectionThread(ConnectionEntry* entry)
{ {
Connection* connection = entry->fConnection; Connection* connection = entry->fConnection;
CallbackReply* reply;
while (fThreadRunning) { while (fThreadRunning) {
uint32 size; uint32 size;
@@ -238,15 +240,30 @@ CallbackServer::ConnectionThread(ConnectionEntry* entry)
if (request == NULL || request->Error() != B_OK) { if (request == NULL || request->Error() != B_OK) {
free(buffer); free(buffer);
continue; continue;
} else if (request != NULL) {
reply = CallbackReply::Create(request->XID(), request->RPCError());
if (reply != NULL) {
connection->Send(reply->Stream().Buffer(),
reply->Stream().Size());
delete reply;
}
free(buffer);
continue;
} }
switch (request->Procedure()) { switch (request->Procedure()) {
case CallbackProcCompound: case CallbackProcCompound:
GetCallback(request->ID())->EnqueueRequest(request, connection); GetCallback(request->ID())->EnqueueRequest(request, connection);
break; break;
case CallbackProcNull: case CallbackProcNull:
dprintf("GOT CB_NULL %x\n", (int)request->XID()); reply = CallbackReply::Create(request->XID());
if (reply != NULL) {
connection->Send(reply->Stream().Buffer(),
reply->Stream().Size());
delete reply;
}
default: default:
free(buffer); free(buffer);
@@ -0,0 +1,61 @@
/*
* Copyright 2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, [email protected]
*/
#ifndef RPCDEFS_H
#define RPCDEFS_H
namespace RPC {
enum {
VERSION = 2
};
enum {
PROGRAM_NFS = 100003,
PROGRAM_NFS_CB = 0x40000000
};
enum {
NFS_VERSION = 4,
NFS_CB_VERSION = 1
};
enum {
CALL = 0,
REPLY = 1
};
enum {
MSG_ACCEPTED = 0,
MSG_DENIED = 1
};
enum AcceptStat {
SUCCESS = 0, /* RPC executed successfully */
PROG_UNAVAIL = 1, /* remote hasn't exported program */
PROG_MISMATCH = 2, /* remote can't support version # */
PROC_UNAVAIL = 3, /* program can't support procedure */
GARBAGE_ARGS = 4, /* procedure can't decode params */
SYSTEM_ERR = 5 /* e.g. memory allocation failure */
};
enum RejectStat {
RPC_MISMATCH = 0, /* RPC version number != 2 */
AUTH_ERROR = 1 /* remote can't authenticate caller */
};
enum AuthFlavour {
AUTH_NONE = 0,
AUTH_SYS = 1
};
} // namespace RPC
#endif // RPCDEFS_H
@@ -11,32 +11,11 @@
#include <util/kernel_cpp.h> #include <util/kernel_cpp.h>
#include "RPCDefs.h"
using namespace RPC; using namespace RPC;
enum {
REPLY = 1
};
enum {
MSG_ACCEPTED = 0,
MSG_DENIED = 1
};
enum accept_stat {
SUCCESS = 0, /* RPC executed successfully */
PROG_UNAVAIL = 1, /* remote hasn't exported program */
PROG_MISMATCH = 2, /* remote can't support version # */
PROC_UNAVAIL = 3, /* program can't support procedure */
GARBAGE_ARGS = 4, /* procedure can't decode params */
SYSTEM_ERR = 5 /* e.g. memory allocation failure */
};
enum reject_stat {
RPC_MISMATCH = 0, /* RPC version number != 2 */
AUTH_ERROR = 1 /* remote can't authenticate caller */
};
Reply::Reply(void *buffer, int size) Reply::Reply(void *buffer, int size)
: :