/* * blockingTCPAcceptor.cpp */ /* pvAccess */ #include #include /* pvData */ #include /* EPICSv3 */ #include #include #include /* standard */ #include using std::ostringstream; 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(in_port_t 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) { errlogSevPrintf(errlogInfo, "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(); BlockingServerTCPTransport::shared_pointer transport = BlockingServerTCPTransport::create( _context, newClient, responseHandler, _receiveBufferSize); // validate connection if(!validateConnection(transport, ipAddrStr)) { transport->close(true); errlogSevPrintf( errlogInfo, "Connection to CA client %s failed to be validated, closing it.", ipAddrStr); return; } errlogSevPrintf(errlogInfo, "Serving to CA client: %s", ipAddrStr); }// accept succeeded else socketOpen = false; } // while } bool BlockingTCPAcceptor::validateConnection(BlockingServerTCPTransport::shared_pointer const & transport, const char* address) { try { transport->verify(); return true; } catch(...) { errlogSevPrintf(errlogInfo, "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)); errlogSevPrintf(errlogInfo, "Stopped accepting connections at %s.", ipAddrStr); epicsSocketDestroy(_serverSocketChannel); } } } }