Beispiel #1
0
//------------------------------------------------------------------------------
// Delete a socket/port connection from this UM.
// ioSock (in) - socket/port connection to be deleted
//------------------------------------------------------------------------------
void
UmModuleIPs::delSocketConn( const IOSocket& ioSock )
{
	boost::mutex::scoped_lock lock( fUmModuleMutex );
	for (unsigned int i=0; i<fUmIPSocketConns.size(); ++i)
	{
		sockaddr sa = ioSock.sa();
		const sockaddr_in* sinp = reinterpret_cast<const sockaddr_in*>(&sa);
		if (fUmIPSocketConns[i]->ipAddress() == sinp->sin_addr.s_addr)
		{

#ifdef MOD_CONN_DEBUG
			std::ostringstream oss;
			oss << "UM " << fUmModuleName << "; deleting connection "<<
				ioSock.toString() << std::endl;
			std::cout << oss.str();
#endif

			fUmIPSocketConns[i]->delSocketConn ( ioSock );

			//..If we just deleted the last connection for this IP, then ad-
			//  vance fNextUmIPSocketIdx to an IP address having connections.
			if (fUmIPSocketConns[i]->count() == 0)
			{
				advanceToNextIP();
			}
			break;
		}
	}
}
Beispiel #2
0
//------------------------------------------------------------------------------
// Get the next socket/port connection belonging to the same UM as ios.
// The selected socket/port connection will be returned in outIos.  It can
// then be used for sending the next response message back to the applicable
// UM module.
// ios (in)        - socket/port connection where a UM request originated from
// outIos (out)    - socket/port connection to use in sending the
//                   corresponding response
// writelock (out) - mutex lock to be used when writing to outIos
// return          - bool indicating if socket/port connection was assigned to
//                   outIos
//------------------------------------------------------------------------------
bool
UmSocketSelector::nextIOSocket(
	const IOSocket& ios,
	SP_UM_IOSOCK&   outIos,
	SP_UM_MUTEX&    writeLock )
{
	sockaddr sa = ios.sa();
	const sockaddr_in* sinp = reinterpret_cast<const sockaddr_in*>(&sa);
	IpAddressUmMap_t::iterator mapIter =
		fIpAddressUmMap.find ( sinp->sin_addr.s_addr );

	if ( mapIter != fIpAddressUmMap.end() )
	{
		unsigned int umIdx = mapIter->second;
		if (fUmModuleIPs[umIdx]->nextIOSocket( outIos, writeLock ))
		{

#ifdef SEL_CONN_DEBUG
			std::ostringstream oss;
			oss << "UM " << fUmModuleIPs[umIdx]->moduleName() <<
				"; in: " << ios.toString() <<
				"; selected out: " << outIos->toString() << std::endl;
			std::cout << oss.str();
#endif

			return true;
		}
	}

	//..This should not happen.  Application is asking for next socket/port for
	//  a connection not in our UM module list.
	return false;
}
Beispiel #3
0
//------------------------------------------------------------------------------
// Delete the specified socket/port from the connection list for the IP address
// referenced by this UmIPSocketConns object.
// ioSock (in) - socket/port connection to be deleted
//
// Not normally a good thing to be using a std::vector if we are going to be
// deleting elements in the middle of the collection.  Very inefficient.
// But this method won't be called often, and we are only dealing with a small
// collection.  Plus we want to use a vector over a list, so that nextIOSocket()
// can benefit from quick random access.
//------------------------------------------------------------------------------
void
UmIPSocketConns::delSocketConn( const IOSocket& ioSock )
{
	for (unsigned int i=0; i<fIOSockets.size(); ++i)
	{
		sockaddr sa1 = fIOSockets[i].fSock->sa();
		const sockaddr_in* sinp1 = reinterpret_cast<const sockaddr_in*>(&sa1);
		sockaddr sa2 = ioSock.sa();
		const sockaddr_in* sinp2 = reinterpret_cast<const sockaddr_in*>(&sa2);
		if (sinp1->sin_port == sinp2->sin_port)
		{
			fIOSockets.erase ( fIOSockets.begin()  + i );

			//..Adjust fNextIOSocketIdx
			//  1a. decrement if fNextIOSocketIdx is after deleted connection
			//  1b. reset to start of vector if we deleted the last connection
			//  2.  reset fNextIOSocketIdx to -1 if we have no more connections
			if (fIOSockets.size() > 0)
			{
				if (fNextIOSocketIdx > static_cast<int>(i))
					fNextIOSocketIdx--;
		
				if ( fNextIOSocketIdx >= static_cast<int>(fIOSockets.size()) )
					fNextIOSocketIdx = 0;
			}
			else
			{
				fNextIOSocketIdx = NEXT_IOSOCKET_UNASSIGNED;
			}

			break;
		}
	}
}
Beispiel #4
0
//------------------------------------------------------------------------------
// Delete a socket/port connection from the UM for which it belongs.
// ioSock (in) - socket/port connection to be deleted
//------------------------------------------------------------------------------
void
UmSocketSelector::delConnection( const IOSocket& ios )
{
	sockaddr sa = ios.sa();
	const sockaddr_in* sinp = reinterpret_cast<const sockaddr_in*>(&sa);
	IpAddressUmMap_t::iterator mapIter =
		fIpAddressUmMap.find ( sinp->sin_addr.s_addr );

	if ( mapIter != fIpAddressUmMap.end() )
	{
		unsigned int umIdx = mapIter->second;
		fUmModuleIPs[umIdx]->delSocketConn( ios );
	}
}
/* this was cut & pasted from InetStreamSocket;
 * is there a clean way to wrap ISS::accept()?
 */
const IOSocket CompressedInetStreamSocket::accept(const struct timespec* timeout)
{
    int clientfd;
    long msecs = 0;

    struct pollfd pfd[1];
    pfd[0].fd = socketParms().sd();
    pfd[0].events = POLLIN;

    if (timeout != 0)
    {
        msecs = timeout->tv_sec * 1000 + timeout->tv_nsec / 1000000;

        if (poll(pfd, 1, msecs) != 1 || (pfd[0].revents & POLLIN) == 0 ||
                pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL))
            return IOSocket(new CompressedInetStreamSocket());
    }

    struct sockaddr sa;

    socklen_t sl = sizeof(sa);

    int e;

    do
    {
        clientfd = ::accept(socketParms().sd(), &sa, &sl);
        e = errno;
    }
    while (clientfd < 0 && (e == EINTR ||
#ifdef ERESTART
                            e == ERESTART ||
#endif
#ifdef ECONNABORTED
                            e == ECONNABORTED ||
#endif
                            false));

    if (clientfd < 0)
    {
        string msg = "CompressedInetStreamSocket::accept: accept() error: ";
        scoped_array<char> buf(new char[80]);
#if STRERROR_R_CHAR_P
        const char* p;

        if ((p = strerror_r(e, buf.get(), 80)) != 0)
            msg += p;

#else
        int p;

        if ((p = strerror_r(e, buf.get(), 80)) == 0)
            msg += buf.get();

#endif
        throw runtime_error(msg);
    }

    if (fSyncProto)
    {
        /* send a byte to artificially synchronize with connect() on the remote */
        char b = 'A';
        int ret;

        ret = ::send(clientfd, &b, 1, 0);
        e = errno;

        if (ret < 0)
        {
            ostringstream  os;
            char blah[80];
#if STRERROR_R_CHAR_P
            const char* p;

            if ((p = strerror_r(e, blah, 80)) != 0)
                os << "CompressedInetStreamSocket::accept sync: " << p;

#else
            int p;

            if ((p = strerror_r(e, blah, 80)) == 0)
                os << "CompressedInetStreamSocket::accept sync: " << blah;

#endif
            ::close(clientfd);
            throw runtime_error(os.str());
        }
        else if (ret == 0)
        {
            ::close(clientfd);
            throw runtime_error("CompressedInetStreamSocket::accept sync: got unexpected error code");
        }
    }

    CompressedInetStreamSocket* ciss = new CompressedInetStreamSocket();
    IOSocket ios;
    sockaddr_in* sin = (sockaddr_in*) &sa;

    if ((sin->sin_addr.s_addr == fSa.sin_addr.s_addr) ||
            sin->sin_addr.s_addr == inet_addr("127.0.0.1"))
        ciss->useCompression = false;

    ios.setSocketImpl(ciss);
    SocketParms sp;
    sp = ios.socketParms();
    sp.sd(clientfd);
    ios.socketParms(sp);
    ios.sa(&sa);
    return ios;
}
Beispiel #6
0
void MasterDBRMNode::run()
{
	ByteStream msg;
	IOSocket *s;
	boost::thread *reader;

	CLEAR_ALARM

	while (!die) {
		s = new IOSocket();
#ifdef BRM_VERBOSE
		cerr << "DBRM Controller waiting..." << endl;
#endif
		serverLock.lock();
		if (dbrmServer != NULL)
			try {
				*s = dbrmServer->accept(&MSG_TIMEOUT);
			}
			catch (runtime_error &e) {
				cerr << e.what() << " continuing...\n";
				serverLock.unlock();
				delete s;
				continue;
			}
		serverLock.unlock();

		if (reloadCmd) {
			if (s->isOpen())
				s->close();
			delete s;
			reload();
			continue;
		}

		if (die || !s->isOpen()) {
			if (s->isOpen())
				s->close();
			delete s;
			continue;
		}

#ifdef BRM_VERBOSE
		cerr << "DBRM Controller: got a connection..." << endl;
#endif
 		mutex.lock();
		activeSessions.push_back(s);
		params = new ThreadParams();
#ifdef BRM_VERBOSE
		cerr << "DBRM Controller: starting another thread" << endl;
#endif
		mutex2.lock();
		
		try {
			reader = new boost::thread(MsgProcessor(this));
		}
		catch (boost::thread_resource_error&) {
			log("DBRM Controller: WARNING!!  Got thread resource error!  Increase system stack size or decrease the # of active sessions.");
#ifdef BRM_VERBOSE
			cerr << "DBRM Controller: WARNING!!  Got thread resource error!  Increase system stack size or decrease the # of active sessions.\n";
#endif
			activeSessions.pop_back();
			sendError(s, ERR_NETWORK);
			sleep(1);  // don't close right away to avoid broken pipe on the client
			s->close();
			delete s;
			delete params;
			mutex2.unlock();
			mutex.unlock();
			continue;
		}
	
		params->t = reader;
		params->sock = s;
		mutex2.unlock();
#ifdef __FreeBSD__
		mutex.unlock();
#endif
	}
	serverLock.lock();
	delete dbrmServer;
	dbrmServer = NULL;
	serverLock.unlock();
}