bool LocalNode::_cmdAcquireSendTokenReply( Command& command ) { const NodeAcquireSendTokenReplyPacket* packet = command.get< NodeAcquireSendTokenReplyPacket >(); serveRequest( packet->requestID ); return true; }
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; }
bool Server::_cmdDestroyConfigReply( co::Command& command ) { const fabric::ServerDestroyConfigReplyPacket* packet = command.get< fabric::ServerDestroyConfigReplyPacket >(); serveRequest( packet->requestID ); return true; }
bool LocalNode::_cmdAckRequest( Command& command ) { const NodeAckRequestPacket* packet = command.get< NodeAckRequestPacket >(); EQASSERT( packet->requestID != EQ_UNDEFINED_UINT32 ); serveRequest( packet->requestID ); return true; }
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; }
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); }
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); }
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; }
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 ); } }
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; }
bool Server::_cmdDestroyConfigReply( co::ICommand& command ) { serveRequest( command.get< uint32_t >( )); return true; }
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 ); }
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); }
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; }
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]); }