/** * Copyright - See the COPYRIGHT that is included with this distribution. * pvAccessCPP is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ #include #include "codec.h" #include #include #include #include #include #include using std::ostringstream; using namespace epics::pvData; namespace epics { namespace pvAccess { BlockingTCPAcceptor::BlockingTCPAcceptor( Context::shared_pointer const & context, ResponseHandlerFactory::shared_pointer const & responseHandlerFactory, int port, int receiveBufferSize) : _context(context), _responseHandlerFactory(responseHandlerFactory), _bindAddress(), _serverSocketChannel(INVALID_SOCKET), _receiveBufferSize(receiveBufferSize), _destroyed(false), _threadId(0) { initialize(port); } BlockingTCPAcceptor::~BlockingTCPAcceptor() { destroy(); } int BlockingTCPAcceptor::initialize(unsigned short port) { // specified bind address _bindAddress.ia.sin_family = AF_INET; _bindAddress.ia.sin_port = htons(port); _bindAddress.ia.sin_addr.s_addr = htonl(INADDR_ANY); char strBuffer[64]; char ipAddrStr[48]; ipAddrToDottedIP(&_bindAddress.ia, ipAddrStr, sizeof(ipAddrStr)); int tryCount = 0; while(tryCount<2) { LOG(logLevelDebug, "Creating acceptor to %s.", ipAddrStr); _serverSocketChannel = epicsSocketCreate(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(_serverSocketChannel==INVALID_SOCKET) { epicsSocketConvertErrnoToString(strBuffer, sizeof(strBuffer)); ostringstream temp; temp<<"Socket create error: "< responseHandler = _responseHandlerFactory->createResponseHandler(); BlockingServerTCPTransportCodec::shared_pointer transport = BlockingServerTCPTransportCodec::create( _context, newClient, responseHandler, _socketSendBufferSize, _receiveBufferSize); // validate connection if(!validateConnection(transport, ipAddrStr)) { transport->close(); LOG( logLevelDebug, "Connection to PVA client %s failed to be validated, closing it.", ipAddrStr); return; } LOG(logLevelDebug, "Serving to PVA client: %s", ipAddrStr); }// accept succeeded else socketOpen = false; } // while } bool BlockingTCPAcceptor::validateConnection(Transport::shared_pointer const & transport, const char* address) { try { transport->verify(0); return true; } catch(...) { LOG(logLevelDebug, "Validation of %s failed.", address); return false; } } void BlockingTCPAcceptor::handleEventsRunner(void* param) { ((BlockingTCPAcceptor*)param)->handleEvents(); } void BlockingTCPAcceptor::destroy() { Lock guard(_mutex); if(_destroyed) return; _destroyed = true; if(_serverSocketChannel!=INVALID_SOCKET) { char ipAddrStr[48]; ipAddrToDottedIP(&_bindAddress.ia, ipAddrStr, sizeof(ipAddrStr)); LOG(logLevelDebug, "Stopped accepting connections at %s.", ipAddrStr); epicsSocketDestroy(_serverSocketChannel); } } } }