⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rpceventhandler.cpp

📁 VXWORKS源代码
💻 CPP
字号:
/* RpcEventHandler *//* Copyright (c) 1999 Wind River Systems, Inc. *//*modification history--------------------01x,17dec01,nel  Add include symbol for diab.01w,02oct01,nel  Move debug hooks into SockStream class.01v,25sep01,nel  Correct prototype error under test harness build.01u,10sep01,nel  Add dcomShow hooks into EventHandler.01t,03aug01,dbs  remove usage of Thread class01s,13jul01,dbs  fix up includes01r,26jun00,dbs  implement presentation context IDs01q,24may00,dbs  add fault diagnostics01p,19aug99,aim  change assert to VXDCOM_ASSERT01o,30jul99,aim  added thread pooling01n,13jul99,aim  syslog api changes01m,09jul99,dbs  use final filenames01l,09jul99,dbs  tidy up logging of packets01k,07jul99,aim  added ostream operator<<01j,02jul99,aim  fix for name changes in RpcPduFactory01i,28jun99,dbs  remove defaultInstance method01h,28jun99,dbs  make sure authn-status is preserved after BIND PDU01g,24jun99,dbs  add authn checking01f,24jun99,dbs  move authn into new class01e,22jun99,dbs  fix includes again01d,18jun99,aim  set data rep on outgoing packets01c,08jun99,aim  rework01b,08jun99,aim  now uses NRpcPdu01a,27may99,aim  created*/#include "RpcEventHandler.h"#include "RpcDispatcher.h"#include "RpcDispatchTable.h"#include "RpcPduFactory.h"#include "RpcIfServer.h"#include "Reactor.h"#include "SCM.h"#include "Syslog.h"#include "TraceCall.h"#include "private/comMisc.h"#include "private/DebugHooks.h"#include "taskLib.h"/* Include symbol for diab */extern "C" int include_vxdcom_RpcEventHandler (void)    {    return 0;    }RpcEventHandler::~RpcEventHandler ()    {    TRACE_CALL;    S_INFO (LOG_RPC, "disconnect: " << (*this));    NTLMSSP* ssp = SCM::ssp ();    if (ssp)	ssp->channelRemove (channelId ());    DELZERO (m_pdu);    }RpcEventHandler::RpcEventHandler (Reactor* reactor)  : SvcHandler<SockStream> (reactor),    m_pdu (0),    m_hostAddr (),    m_peerAddr (),    m_dispatcher (0),    m_creatorTaskId (::taskIdSelf ()),    m_acceptor (0)    {    TRACE_CALL;    NTLMSSP* ssp = SCM::ssp ();    if (ssp)	ssp->channelAdd (channelId ());    }RpcEventHandler::RpcEventHandler    (    Reactor*		reactor,    RpcDispatcher*	dispatcher    )  : SvcHandler<SockStream> (reactor),    m_pdu (0),    m_hostAddr (),    m_peerAddr (),    m_dispatcher (dispatcher),    m_creatorTaskId (::taskIdSelf ()),    m_acceptor (0)    {    TRACE_CALL;    COM_ASSERT (m_dispatcher);    NTLMSSP* ssp = SCM::ssp ();    if (ssp)	ssp->channelAdd (channelId ());    }int RpcEventHandler::open (void* pv)    {    acceptorSet (static_cast<RpcIfServer*> (pv));    if (concurrency() == RpcIfServer::ThreadPerConnection)	{	COM_ASSERT (0);	// NYI	}    return super::open (pv);    }int RpcEventHandler::close (unsigned long flags)    {    return super::close (flags);    }const INETSockAddr&RpcEventHandler::peerAddr ()    {    stream().peerAddrGet (m_peerAddr);    return m_peerAddr;    }const INETSockAddr&RpcEventHandler::hostAddr ()    {    stream().hostAddrGet (m_hostAddr);    return m_hostAddr;    }intRpcEventHandler::handleInput (REACTOR_HANDLE handle)    {    TRACE_CALL;    if (concurrency () == RpcIfServer::ThreadPooled)	{	if (::taskIdSelf () == m_creatorTaskId)	    {	    reactorGet()->handlerRemove (this,					 EventHandler::READ_MASK |					 EventHandler::DONT_CALL);	    return threadPool()->enqueue (this);	    }	}    // Any strategy other than thread-per-connection will eventually get    // here.  If we're in the single-threaded implementation or the    // thread-pool, we still have to pass this way.    int result = process ();    // Now, we look again to see if we're in the thread-pool    // implementation.  If so then we need to re-register ourselves with    // the reactor so that we can get more work when it is available.    if (concurrency () == RpcIfServer::ThreadPooled)	{	if (result != -1)	    reactorGet()->handlerAdd (this, EventHandler::READ_MASK);	}    return result;    }int RpcEventHandler::process ()    {    TRACE_CALL;    const int buflen = 1024;    char buf [buflen];    char* pbuf = buf;    ssize_t n = stream().recv (pbuf, buflen);    if (n > 0)	{	S_DEBUG (LOG_RPC, (*this) << " read: " << (int) n);	/* We only process the first fragment of the packet because */	/* RpcPdu doesn't store the data contiguiouly in memory at the */	/* moment so we can't just feed the byte stream into the debug */	/* hook */	stream ().processDebugOutput (pRpcServerInput, (BYTE *)pbuf, n);	}    int result = -1; // guilty until proved innocent    while (n > 0)	{	if (m_pdu == 0 && (m_pdu = new RpcPdu ()) == 0)	    break;		// ENOMEM	int consumed = m_pdu->append (pbuf, n);	if (m_pdu->complete ())	    {	    result = dispatchPdu (*m_pdu);	    DELZERO (m_pdu);	    if (result != 0)		break;	    }	else	    {	    S_DEBUG (LOG_RPC, "pdu not complete");	    result = 0;		// hang on for more data	    }	// move offset into appended data	pbuf += consumed;	n -= consumed;	}        if (result < 0)	DELZERO (m_pdu);    return result;    }    intRpcEventHandler::dispatchAuth3 (const RpcPdu& auth3Pdu)    {    TRACE_CALL;    NTLMSSP* ssp = SCM::ssp ();    if (ssp)	ssp->serverAuth3Validate (channelId (), auth3Pdu);    return 0;    }intRpcEventHandler::dispatchBind (const RpcPdu& bindPdu)    {    TRACE_CALL;    if (m_dispatcher == 0)	return -1;    RpcPdu responsePdu;    IID iid = bindPdu.bind().presCtxList.presCtxElem[0].abstractSyntax.id;    USHORT presCtxId = bindPdu.bind().presCtxList.presCtxElem[0].presCtxId;    // If the dispatcher supports this interface-ID, then we are bound    // to it, via the given presentation-context ID...    if (m_dispatcher->supportsInterface (iid))	RpcPduFactory::formatBindAckPdu (bindPdu,					 responsePdu,					 reinterpret_cast<ULONG> (this));    else	RpcPduFactory::formatBindNakPdu (bindPdu, responsePdu);    // Process authentication trailers...    NTLMSSP* ssp = SCM::ssp ();    if (ssp)	ssp->serverBindValidate (channelId (),				 bindPdu,				 responsePdu);    // Reply to the BIND...    int result = reply (bindPdu, responsePdu);    // If successful, record the presentation context...    if (result == 0)	m_presCtxMap [presCtxId] = iid;    return result;    }intRpcEventHandler::dispatchRequest (const RpcPdu& requestPdu)    {    RpcPdu responsePdu;    // Find which presentation context this request is for, and so,    // which interface ID to use...    USHORT presCtxId = requestPdu.request().presCtxId;    PresCtxMap::const_iterator i = m_presCtxMap.find (presCtxId);    if (i == m_presCtxMap.end ())	return -1;        // Use the presentation context to select the right IID...        m_dispatcher->dispatch (requestPdu,			    responsePdu,			    channelId (),			    (*i).second);    // Process authentication trailers...    NTLMSSP* ssp = SCM::ssp ();    if (ssp)	ssp->serverRequestValidate (channelId (),				    requestPdu,				    responsePdu);            return reply (requestPdu, responsePdu);    }intRpcEventHandler::dispatchPdu (const RpcPdu& pdu)    {    TRACE_CALL;        S_DEBUG (LOG_RPC, "recvPdu: " << pdu);    if (pdu.isRequest ())	return dispatchRequest (pdu);    else if (pdu.isBind ())	return dispatchBind (pdu);    else if (pdu.isAuth3 ())	return dispatchAuth3 (pdu);    return 0;    }int RpcEventHandler::sendPdu (RpcPdu& pdu)    {    TRACE_CALL;    size_t len;    char *buf = 0;    int status = -1;    S_DEBUG (LOG_RPC, "sendPdu: " << pdu);    if (pdu.makeReplyBuffer (buf, len) < 0)	stream().close ();    else if (stream().send (buf, len) == len)	{	stream ().processDebugOutput (pRpcServerOutput, (BYTE *)buf, len);	status = 0;	}    delete [] buf;    return status;    }intRpcEventHandler::reply (const RpcPdu& pdu, RpcPdu& replyPdu)    {    TRACE_CALL;    replyPdu.drepSet (pdu.drep ());    if (replyPdu.isFault ())	{	S_ERR (LOG_RPC, "RxREQUEST:" << pdu);	S_ERR (LOG_RPC, "TxFAULT:" << replyPdu);	}        // send reply    return sendPdu (replyPdu);    }intRpcEventHandler::channelId () const    {    TRACE_CALL;    return reinterpret_cast<int> (this);    }int RpcEventHandler::concurrency ()    {	    TRACE_CALL;    return acceptorGet()->concurrency ();    }ThreadPool* RpcEventHandler::threadPool ()    {    TRACE_CALL;    return acceptorGet()->threadPool ();    }RpcIfServer* RpcEventHandler::acceptorGet () const    {    TRACE_CALL;    return m_acceptor;    }RpcIfServer* RpcEventHandler::acceptorSet (RpcIfServer* pRpcIfServer)    {    TRACE_CALL;    return m_acceptor = pRpcIfServer;    }    ostream& operator<< (ostream& os, const RpcEventHandler& eh)    {    RpcEventHandler* p = const_cast<RpcEventHandler*> (&eh);    os << p->hostAddr ()       << " => "       << p->peerAddr ()       << " (fd="       << p->handleGet ()       << ") ";    return os;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -