예제 #1
0
bool LocalNode::_cmdAcquireSendTokenReply( Command& command )
{
    const NodeAcquireSendTokenReplyPacket* packet = 
        command.get< NodeAcquireSendTokenReplyPacket >();
    serveRequest( packet->requestID );
    return true;
}
예제 #2
0
bool LocalNode::_cmdDisconnect( Command& command )
{
    EQASSERT( _inReceiverThread( ));

    const NodeDisconnectPacket* packet = command.get< NodeDisconnectPacket >();

    NodePtr node = static_cast<Node*>( getRequestData( packet->requestID ));
    EQASSERT( node.isValid( ));

    ConnectionPtr connection = node->_outgoing;
    if( connection.isValid( ))
    {
        node->_state    = STATE_CLOSED;
        node->_outgoing = 0;

        _removeConnection( connection );

        EQASSERT( _connectionNodes.find( connection )!=_connectionNodes.end( ));
        _objectStore->removeInstanceData( node->_id );
        _connectionNodes.erase( connection );
        {
            base::ScopedMutex< base::SpinLock > mutex( _nodes );
            _nodes->erase( node->_id );
        }

        EQINFO << node << " disconnected from " << this << " connection used " 
               << connection->getRefCount() << std::endl;
    }

    EQASSERT( node->_state == STATE_CLOSED );
    serveRequest( packet->requestID );
    return true;
}
예제 #3
0
bool Server::_cmdDestroyConfigReply( co::Command& command ) 
{
    const fabric::ServerDestroyConfigReplyPacket* packet = 
        command.get< fabric::ServerDestroyConfigReplyPacket >();

    serveRequest( packet->requestID );
    return true;
}
예제 #4
0
bool LocalNode::_cmdAckRequest( Command& command )
{
    const NodeAckRequestPacket* packet = command.get< NodeAckRequestPacket >();
    EQASSERT( packet->requestID != EQ_UNDEFINED_UINT32 );

    serveRequest( packet->requestID );
    return true;
}
예제 #5
0
파일: command.cpp 프로젝트: qqdiguo/Collage
 bool _cmdDataReply( co::ICommand& command )
 {
     TEST( !_gotAsync );
     const uint32_t request = command.get< uint32_t >();
     const uint32_t result = command.get< uint32_t >();
     TEST( result == ++_counter );
     serveRequest( request, result );
     return true;
 }
예제 #6
0
int main(int argc, char *argv[])
{
    struct requestMsg req;
    pid_t pid;
    ssize_t msgLen;
    int serverId;
    struct sigaction sa;

    // create server message queue
    serverId = msgget(SERVER_KEY, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IWGRP);
    if (serverId == -1) {
        errExit("msgget");
    }

    // establish SIGCHLD handler to reap terminated children
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    sa.sa_handler = grimReaper;
    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
        errExit("sigaction");
    }

    // read requests, handle each in separate child process
    for (;;) {
        // get a request
        msgLen = msgrcv(serverId, &req, REQ_MSG_SIZE, 0, 0);
        if (msgLen == -1) {
            if (errno == EINTR) { // interrupted by SIGCHLD?
                continue;
            }

            errMsg("msgrcv"); // some other error
            break; // so terminate loop
        }

        pid = fork(); // create child process
        if (pid == -1) {
            errExit("fork");
            break;
        }

        if (pid == 0) {
            serveRequest(&req);
            _exit(EXIT_SUCCESS);
        }

        // parent loops to receive next request
    }

    // if msgrcv() or fork() fails, remove server MQ and exit
    if (msgctl(serverId, IPC_RMID, NULL) == -1) {
        errExit("msgctl");
    }

    exit(EXIT_SUCCESS);
}
예제 #7
0
int
main(int argc, char *argv[])
{
    struct requestMsg req;
    pid_t pid;
    ssize_t msgLen;
    int serverId;
    struct sigaction sa;

    /* Create server message queue */

    serverId = msgget(SERVER_KEY, IPC_CREAT | IPC_EXCL |
                            S_IRUSR | S_IWUSR | S_IWGRP);
    if (serverId == -1)
        errExit("msgget");

    /* Establish SIGCHLD handler to reap terminated children */

    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    sa.sa_handler = grimReaper;
    if (sigaction(SIGCHLD, &sa, NULL) == -1)
        errExit("sigaction");

    /* Read requests, handle each in a separate child process */

    for (;;) {
        msgLen = msgrcv(serverId, &req, REQ_MSG_SIZE, 0, 0);
        if (msgLen == -1) {
            if (errno == EINTR)         /* Interrupted by SIGCHLD handler? */
                continue;               /* ... then restart msgrcv() */
            errMsg("msgrcv");           /* Some other error */
            break;                      /* ... so terminate loop */
        }

        pid = fork();                   /* Create child process */
        if (pid == -1) {
            errMsg("fork");
            break;
        }

        if (pid == 0) {                 /* Child handles request */
            serveRequest(&req);
            _exit(EXIT_SUCCESS);
        }

        /* Parent loops to receive next client request */
    }

    /* If msgrcv() or fork() fails, remove server MQ and exit */

    if (msgctl(serverId, IPC_RMID, NULL) == -1)
        errExit("msgctl");
    exit(EXIT_SUCCESS);
}
예제 #8
0
bool LocalNode::_cmdGetNodeDataReply( Command& command )
{
    EQASSERT( _inReceiverThread( ));

    const NodeGetNodeDataReplyPacket* packet = 
        command.get< NodeGetNodeDataReplyPacket >();
    EQVERB << "cmd get node data reply: " << packet << std::endl;

    const uint32_t requestID = packet->requestID;
    const NodeID& nodeID = packet->nodeID;

    // No locking needed, only recv thread writes
    NodeHash::const_iterator i = _nodes->find( nodeID );
    if( i != _nodes->end( ))
    {
        // Requested node connected to us in the meantime
        NodePtr node = i->second;
        
        node->ref( CO_REFERENCED_PARAM );
        serveRequest( requestID, node.get( ));
        return true;
    }

    if( packet->nodeType == NODETYPE_CO_INVALID )
    {
        serveRequest( requestID, (void*)0 );
        return true;
    }

    // new node: create and add unconnected node
    NodePtr node = createNode( packet->nodeType );
    EQASSERT( node.isValid( ));

    std::string data = packet->nodeData;
    if( !node->deserialize( data ))
        EQWARN << "Failed to initialize node data" << std::endl;
    EQASSERT( data.empty( ));

    node->ref( CO_REFERENCED_PARAM );
    serveRequest( requestID, node.get( ));
    return true;
}
예제 #9
0
void LocalNode::ackRequest( NodePtr node, const uint32_t requestID )
{
    if( requestID == EQ_UNDEFINED_UINT32 ) // no need to ack operation
        return;

    if( node == this ) // OPT
        serveRequest( requestID );
    else
    {
        NodeAckRequestPacket reply( requestID );
        node->send( reply );
    }
}
예제 #10
0
bool LocalNode::_cmdRemoveListener( Command& command )
{
    NodeRemoveListenerPacket* packet = 
        command.getModifiable< NodeRemoveListenerPacket >();

    ConnectionDescriptionPtr description =
        new ConnectionDescription( packet->connectionData );
    EQCHECK( command.getNode()->removeConnectionDescription( description ));

    if( command.getNode() != this )
        return true;

    EQASSERT( packet->connection );
    ConnectionPtr connection = packet->connection;
    packet->connection = 0;
    connection->unref( CO_REFERENCED_PARAM );

    if( connection->getDescription()->type >= CONNECTIONTYPE_MULTICAST )
    {
        base::ScopedMutex<> mutex( _outMulticast );
        for( MCDatas::iterator i = _multicasts.begin();
             i != _multicasts.end(); ++i )
        {
            if( i->connection == connection )
            {
                _multicasts.erase( i );
                break;
            }
        }
    }

    _incoming.removeConnection( connection );
    EQASSERT( _connectionNodes.find( connection ) != _connectionNodes.end( ));
    _connectionNodes.erase( connection );
    serveRequest( packet->requestID );
    return true;
}
예제 #11
0
bool Server::_cmdDestroyConfigReply( co::ICommand& command )
{
    serveRequest( command.get< uint32_t >( ));
    return true;
}
예제 #12
0
void FalhttpdClient::serve()
{
    m_log->log( LOGLEVEL_DEBUG, "Serving client "+ m_sRemote );

    // get the header
    String sHeader;
    StreamBuffer si( new SocketInputStream( m_nSocket ) );
    uint32 chr;
    while ( ! sHeader.endsWith("\r\n") && si.get(chr) )
    {
        // do nothing
        sHeader.append( chr );
    }

    if ( ! sHeader.endsWith("\r\n") )
    {
        m_log->log( LOGLEVEL_WARN, "Client "+ m_sRemote + " has sent an invalid header." );
        return;
    }
    // remove trailing \r\n
    sHeader.remove( sHeader.length()-2, 2 );

    // parse the header; must be in format GET/POST/HEAD 'uri' HTTP/1.x
    uint32 p1, p2;
    p1 = sHeader.find( " " );
    p2 = sHeader.rfind( " " );
    if ( p1 == p2 )
    {
        sHeader.trim();
        m_log->log( LOGLEVEL_WARN, "Client "+ m_sRemote + " has sent an invalid header: " + sHeader );
        return;
    }

    String sRequest = sHeader.subString( 0, p1 );
    String sUri = sHeader.subString( p1+1, p2 );
    String sProto = sHeader.subString( p2+1 );

    // a bit of formal control
    int type = sRequest == "GET" ? 1 :
               ( sRequest == "POST"  ? 2 : ( sRequest == "HEAD" ? 3 : 0 ) );

    if ( type == 0 )
    {
        m_log->log( LOGLEVEL_WARN, "Client "+ m_sRemote + " has sent an invalid type: " + sHeader );
        replyError( 400, "Invalid requests type" );
        return;
    }

    URI uri( sUri );
    if( ! uri.isValid() )
    {
        m_log->log( LOGLEVEL_WARN, "Client "+ m_sRemote + " has sent an invalid URI: " + sHeader );
        replyError( 400, "Invalid invalid uri" );
        return;
    }

    if( sProto != "HTTP/1.0" && sProto != "HTTP/1.1" )
    {
        m_log->log( LOGLEVEL_WARN, "Client "+ m_sRemote + " has sent an invalid Protocol: " + sHeader );
        replyError( 505 );
        return;
    }

    // ok, we got a valid header -- proceed in serving the request.
    serveRequest( sRequest, sUri, sProto, &si );
}
예제 #13
0
int
main(int argc, char *argv[])
{
	struct requestMsg req;
	pid_t pid;
	ssize_t msgLen;
	int serverId;
	int fd;
	int nread;
	int seqNum;
	struct sigaction sa;
	char *file = "/tmp/seqnum.txt";
	
	/* Create server message queue */

	serverId = msgget(SERVER_KEY, IPC_CREAT |
			  S_IRUSR | S_IWUSR | S_IWGRP);

	if (serverId == -1)
		errExit("msgget");

	/* Establish SIGCHLD handler to reap terminated children */

	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_RESTART;
	sa.sa_handler = grimReaper;
	if (sigaction(SIGCHLD, &sa, NULL) == -1)
		errExit("sigaction");

	fd = open(file, O_RDWR | O_DSYNC,  S_IRUSR | S_IWUSR);
	if (fd != -1) {
		nread = read(fd, &seqNum, sizeof(int));
		if (nread == -1)
			errExit("read");
	} else if (fd == -1 && errno == ENOENT) {
		seqNum = 0;
		fd = open(file, O_RDWR | O_CREAT | O_DSYNC, S_IRUSR | S_IWUSR);
	}

	/* catch error on either open's */
	if (fd == -1)
		errExit("open");
	
	/* Read requests, handle each in a separate child process */

	for (;;) {
		msgLen = msgrcv(serverId, &req, REQ_MSG_SIZE, 0, 0);
		if (msgLen == -1) {
			if (errno == EINTR)         /* Interrupted by SIGCHLD handler? */
				continue;               /* ... then restart msgrcv() */
			errMsg("msgrcv");           /* Some other error */
			break;                      /* ... so terminate loop */
		}

		pid = fork();                   /* Create child process */
		if (pid == -1) {
			errMsg("fork");
			break;
		}

		if (pid == 0) {                 /* Child handles request */
			serveRequest(&req, seqNum);
			_exit(EXIT_SUCCESS);
		}

		seqNum += req.seqLen;
		/* Parent loops to receive next client request */
	}

	/* If msgrcv() or fork() fails, remove server MQ and exit */

	if (msgctl(serverId, IPC_RMID, NULL) == -1)
		errExit("msgctl");
	exit(EXIT_SUCCESS);
}
예제 #14
0
bool LocalNode::_cmdConnectReply( Command& command )
{
    EQASSERT( !command.getNode( ));
    EQASSERT( _inReceiverThread( ));

    const NodeConnectReplyPacket* packet =
        command.get< NodeConnectReplyPacket >();
    ConnectionPtr connection = _incoming.getConnection();

    const NodeID& nodeID = packet->nodeID;

    EQVERB << "handle connect reply " << packet << std::endl;
    EQASSERT( _connectionNodes.find( connection ) == _connectionNodes.end( ));

    NodePtr remoteNode;

    // No locking needed, only recv thread modifies
    NodeHash::const_iterator i = _nodes->find( nodeID );
    if( i != _nodes->end( ))
        remoteNode = i->second;

    if( nodeID == NodeID::ZERO || // connection refused
        // Node exists, probably simultaneous connect
        ( remoteNode.isValid() && remoteNode->isConnected( )))
    {
        EQINFO << "ignoring connect reply, node already connected" << std::endl;
        _removeConnection( connection );
        
        if( packet->requestID != EQ_UNDEFINED_UINT32 )
            serveRequest( packet->requestID, false );
        
        return true;
    }

    // create and add node
    if( !remoteNode )
    {
        if( packet->requestID != EQ_UNDEFINED_UINT32 )
        {
            void* ptr = getRequestData( packet->requestID );
            EQASSERT( dynamic_cast< Node* >( (Dispatcher*)ptr ));
            remoteNode = static_cast< Node* >( ptr );
        }
        else
            remoteNode = createNode( packet->nodeType );
    }

    EQASSERT( remoteNode->getType() == packet->nodeType );
    EQASSERT( remoteNode->_state == STATE_CLOSED );

    std::string data = packet->nodeData;
    if( !remoteNode->deserialize( data ))
        EQWARN << "Error during node initialization" << std::endl;
    EQASSERT( data.empty( ));
    EQASSERT( remoteNode->_id == nodeID );

    remoteNode->_outgoing = connection;
    remoteNode->_state    = STATE_CONNECTED;
    
    _connectionNodes[ connection ] = remoteNode;
    {
        base::ScopedMutex< base::SpinLock > mutex( _nodes );
        _nodes.data[ remoteNode->_id ] = remoteNode;
    }
    EQVERB << "Added node " << nodeID << std::endl;

    if( packet->requestID != EQ_UNDEFINED_UINT32 )
        serveRequest( packet->requestID, true );

    NodeConnectAckPacket ack;
    remoteNode->send( ack );

    _connectMulticast( remoteNode );
    return true;
}
예제 #15
0
void RequestModule::serveRequest(Input inputs[INPUT_MAX_COUNT]) {
    // Validates the request
    if(! SecurityModule::isValidRequest(inputs[0])) {
        // The request is invalid
        CommunicationModule::sendErrorResponse(INVALID_INPUT);
        return;
    }

    // Parses the request
    Request request = atoi(inputs[0]);

    // Validates the petitioner username
    if(! SecurityModule::isValidUsername(inputs[1])) {
        // The petitioner username is invalid
        CommunicationModule::sendErrorResponse(INVALID_INPUT);
        return;
    }

    // Validates the remaining input parameters
    switch(request) {
    case LOGOUT :
    case REFRESH_TTL :
    case REQUEST_STATE :
    case REQUEST_USERS :
    case TOGGLE_LIGHT :
    case TOGGLE_LOCK :
        break;

    case ADD_USER : {
            if(! SecurityModule::isValidUsername(inputs[2])) {
                CommunicationModule::sendErrorResponse(INVALID_INPUT);
                return;
            }

            if(! SecurityModule::isValidPassword(inputs[3])) {
                CommunicationModule::sendErrorResponse(INVALID_INPUT);
                return;
            }

            break;
        }

    case CHANGE_PASSWORD : {
            if(! SecurityModule::isValidPassword(inputs[2])) {
                CommunicationModule::sendErrorResponse(INVALID_INPUT);
                return;
            }

            break;
        }

    case LOGIN : {
            if(! SecurityModule::isValidPassword(inputs[2])) {
                CommunicationModule::sendErrorResponse(INVALID_INPUT);
                return;
            }

            break;
        }

    case REMOVE_USER : {
            if(! SecurityModule::isValidUsername(inputs[2])) {
                CommunicationModule::sendErrorResponse(INVALID_INPUT);
                return;
            }

            break;
        }

    default : {
            // Invalid request
            CommunicationModule::sendErrorResponse(INVALID_INPUT);
            return;
        }
    }

    // Serves the request safely
    serveRequest(request, &inputs[1]);
}