OutputMessage_ptr OutputMessagePool::getOutputMessage(Protocol* protocol, bool autosend /*= true*/) { #ifdef __DEBUG_NET_DETAIL__ std::cout << "request output message - auto = " << autosend << std::endl; #endif if(!m_isOpen){ return OutputMessage_ptr(); } boost::recursive_mutex::scoped_lock lockClass(m_outputPoolLock); if(protocol->getConnection() == NULL){ return OutputMessage_ptr(); } if(m_outputMessages.empty()){ OutputMessage* msg = new OutputMessage(); m_outputMessages.push_back(msg); #ifdef __TRACK_NETWORK__ m_allOutputMessages.push_back(msg); #endif } OutputMessage_ptr outputmessage; outputmessage.reset(m_outputMessages.back(), boost::bind(&OutputMessagePool::releaseMessage, this, _1)); m_outputMessages.pop_back(); configureOutputMessage(outputmessage, protocol, autosend); return outputmessage; }
bool DatabaseSQLite::executeQuery(const std::string &query) { OTSYS_THREAD_LOCK_CLASS lockClass(sqliteLock); if(!m_connected) return false; #ifdef __SQL_QUERY_DEBUG__ std::cout << "SQLITE QUERY: " << query << std::endl; #endif std::string buf = _parse(query); sqlite3_stmt* stmt; // prepares statement if(OTSYS_SQLITE3_PREPARE(m_handle, buf.c_str(), buf.length(), &stmt, NULL) != SQLITE_OK) { sqlite3_finalize(stmt); std::cout << "OTSYS_SQLITE3_PREPARE(): SQLITE ERROR: " << sqlite3_errmsg(m_handle) << " (" << buf << ")" << std::endl; return false; } // executes it once int32_t ret = sqlite3_step(stmt); if(ret != SQLITE_OK && ret != SQLITE_DONE && ret != SQLITE_ROW) { sqlite3_finalize(stmt); std::cout << "sqlite3_step(): SQLITE ERROR: " << sqlite3_errmsg(m_handle) << std::endl; return false; } // closes statement // at all not sure if it should be debugged - query was executed correctly... sqlite3_finalize(stmt); return true; }
void Connection::closeConnectionTask() { //dispatcher thread std::lock_guard<std::recursive_mutex> lockClass(m_connectionLock); if (m_connectionState != CONNECTION_STATE_REQUEST_CLOSE) { std::cout << "Error: [Connection::closeConnectionTask] m_connectionState = " << m_connectionState << std::endl; return; } if (m_protocol) { m_protocol->setConnection(Connection_ptr()); m_protocol->releaseProtocol(); m_protocol = nullptr; } m_connectionState = CONNECTION_STATE_CLOSING; if (m_pendingWrite == 0 || m_writeError) { closeSocket(); releaseConnection(); m_connectionState = CONNECTION_STATE_CLOSED; } else { //will be closed by onWriteOperation/handleWriteTimeout/handleReadTimeout instead } }
OutputMessage_ptr OutputMessagePool::getOutputMessage(Protocol* protocol, bool autosend /*= true*/) { #ifdef __DEBUG_NET_DETAIL__ std::cout << "request output message - auto = " << autosend << std::endl; #endif if(m_shutdown) return OutputMessage_ptr(); OTSYS_THREAD_LOCK_CLASS lockClass(m_outputPoolLock); if(!protocol->getConnection()) return OutputMessage_ptr(); if(m_outputMessages.empty()) { OutputMessage* msg = new OutputMessage(); m_outputMessages.push_back(msg); #ifdef __TRACK_NETWORK__ m_allOutputMessages.push_back(msg); #endif } OutputMessage_ptr omsg; omsg.reset(m_outputMessages.back(), boost::bind(&OutputMessagePool::releaseMessage, this, _1)); m_outputMessages.pop_back(); configureOutputMessage(omsg, protocol, autosend); return omsg; }
//TODO: render only the necessary void Screen::render() { boost::mutex::scoped_lock lockClass(m_screenMutex); if(m_clearScreen) { clear(); m_clearScreen = false; } move(0, 0); printw("\n"); Monitor::instance()->render(); attron(COLOR_PAIR(1)); printw(" Lastest Actions\n"); attroff(COLOR_PAIR(1)); if(m_notifications.size() == 0) printw(" None yet\n"); else for(NotificationList::iterator it = m_notifications.begin(); it != m_notifications.end(); ++it) printw((boost::str(boost::format(" %1%\n") % (*it))).c_str()); printw("\n"); refresh(); }
void Connection::handleWriteError(const boost::system::error_code& error) { #ifdef __DEBUG_NET_DETAIL__ PRINT_ASIO_ERROR("Writing - detail"); #endif boost::recursive_mutex::scoped_lock lockClass(m_connectionLock); if(error == boost::asio::error::operation_aborted){ //Operation aborted because connection will be closed //Do NOT call closeConnection() from here } else if(error == boost::asio::error::eof){ //No more to read closeConnection(); } else if(error == boost::asio::error::connection_reset || error == boost::asio::error::connection_aborted){ //Connection closed remotely closeConnection(); } else{ PRINT_ASIO_ERROR("Writing"); closeConnection(); } m_writeError = true; }
void ConnectionManager::addAttempt(uint32_t clientIp, int32_t protocolId, bool success) { boost::recursive_mutex::scoped_lock lockClass(m_connectionManagerLock); if(!clientIp) return; IpLoginMap::iterator it = ipLoginMap.find(clientIp); if(it == ipLoginMap.end()) { LoginBlock tmp; tmp.lastLogin = tmp.loginsAmount = 0; tmp.lastProtocol = 0x00; ipLoginMap[clientIp] = tmp; it = ipLoginMap.find(clientIp); } if(it->second.loginsAmount > g_config.getNumber(ConfigManager::LOGIN_TRIES)) it->second.loginsAmount = 0; int32_t currentTime = time(NULL); if(!success || (currentTime < it->second.lastLogin + (int32_t)g_config.getNumber(ConfigManager::RETRY_TIMEOUT) / 1000)) it->second.loginsAmount++; else it->second.loginsAmount = 0; it->second.lastLogin = currentTime; it->second.lastProtocol = protocolId; }
OutputMessage_ptr OutputMessagePool::getOutputMessage(Protocol* protocol, bool autosend /*= true*/) { if (!m_isOpen) { return OutputMessage_ptr(); } std::lock_guard<std::recursive_mutex> lockClass(m_outputPoolLock); if (!protocol->getConnection()) { return OutputMessage_ptr(); } if (m_outputMessages.empty()) { OutputMessage* msg = new OutputMessage(); m_outputMessages.push_back(msg); } OutputMessage_ptr outputmessage; outputmessage.reset(m_outputMessages.back(), std::bind(&OutputMessagePool::releaseMessage, this, std::placeholders::_1)); m_outputMessages.pop_back(); configureOutputMessage(outputmessage, protocol, autosend); return outputmessage; }
bool Ban::acceptConnection(uint32_t clientip) { std::lock_guard<std::recursive_mutex> lockClass(lock); uint64_t currentTime = OTSYS_TIME(); auto it = ipConnectMap.find(clientip); if (it == ipConnectMap.end()) { ipConnectMap.emplace(clientip, ConnectBlock(currentTime, 0, 1)); return true; } ConnectBlock& connectBlock = it->second; if (connectBlock.blockTime > currentTime) { connectBlock.blockTime += 250; return false; } int64_t timeDiff = currentTime - connectBlock.lastAttempt; connectBlock.lastAttempt = currentTime; if (timeDiff <= 5000) { if (++connectBlock.count > 5) { connectBlock.count = 0; if (timeDiff <= 500) { connectBlock.blockTime = currentTime + 3000; return false; } } } else { connectBlock.count = 1; } return true; }
Connection_ptr ConnectionManager::createConnection(boost::asio::ip::tcp::socket* socket, boost::asio::io_service& io_service, ServicePort_ptr servicer) { boost::recursive_mutex::scoped_lock lockClass(m_connectionManagerLock); Connection_ptr connection = Connection_ptr(new Connection(socket, io_service, servicer)); m_connections.push_back(connection); return connection; }
Connection_ptr ConnectionManager::createConnection(boost::asio::io_service& io_service, ConstServicePort_ptr servicePort) { std::lock_guard<std::mutex> lockClass(connectionManagerLock); auto connection = std::make_shared<Connection>(io_service, servicePort); connections.insert(connection); return connection; }
void OutputMessagePool::sendAll() { boost::recursive_mutex::scoped_lock lockClass(m_outputPoolLock); OutputMessageMessageList::iterator it; for(it = m_toAddQueue.begin(); it != m_toAddQueue.end();) { //drop messages that are older than 10 seconds if(OTSYS_TIME() - (*it)->getFrame() > 10 * 1000) { (*it)->getProtocol()->onSendMessage(*it); it = m_toAddQueue.erase(it); continue; } (*it)->setState(OutputMessage::STATE_ALLOCATED); m_autoSendOutputMessages.push_back(*it); ++it; } m_toAddQueue.clear(); for(it = m_autoSendOutputMessages.begin(); it != m_autoSendOutputMessages.end();) { OutputMessage_ptr omsg = *it; #ifdef __NO_PLAYER_SENDBUFFER__ //use this define only for debugging bool v = 1; #else //It will send only messages bigger then 1 kb or with a lifetime greater than 10 ms bool v = omsg->getMessageLength() > 1024 || (m_frameTime - omsg->getFrame() > 10); #endif if(v) { #ifdef __DEBUG_NET_DETAIL__ std::cout << "Sending message - ALL" << std::endl; #endif if(omsg->getConnection()) { if(!omsg->getConnection()->send(omsg)) { // Send only fails when connection is closing (or in error state) // This call will free the message omsg->getProtocol()->onSendMessage(omsg); } } else { #ifdef __DEBUG_NET__ std::cout << "Error: [OutputMessagePool::send] NULL connection." << std::endl; #endif } it = m_autoSendOutputMessages.erase(it); } else ++it; } }
void Connection::onReadTimeout() { std::lock_guard<std::recursive_mutex> lockClass(m_connectionLock); if (m_pendingRead > 0 || m_readError) { closeSocket(); closeConnection(); } }
void Connection::onReadTimeout() { boost::recursive_mutex::scoped_lock lockClass(m_connectionLock); if(m_pendingRead > 0 || m_readError){ closeSocket(); closeConnection(); } }
void Connection::onWriteTimeout() { boost::recursive_mutex::scoped_lock lockClass(m_connectionLock); if(m_pendingWrite > 0 || m_writeError){ closeSocket(); closeConnection(); } }
void Connection::onWriteTimeout() { std::lock_guard<std::recursive_mutex> lockClass(m_connectionLock); if (m_pendingWrite > 0 || m_writeError) { closeSocket(); closeConnection(); } }
Connection_ptr ConnectionManager::createConnection(boost::asio::ip::tcp::socket* socket, boost::asio::io_service& io_service, ServicePort_ptr servicer) { std::lock_guard<std::recursive_mutex> lockClass(m_connectionManagerLock); Connection_ptr connection = Connection_ptr(new Connection(socket, io_service, servicer)); m_connections.insert(connection); return connection; }
bool ConnectionManager::isDisabled(uint32_t clientIp, int32_t protocolId) { boost::recursive_mutex::scoped_lock lockClass(m_connectionManagerLock); int32_t maxLoginTries = g_config.getNumber(ConfigManager::LOGIN_TRIES); if(!maxLoginTries || !clientIp) return false; IpLoginMap::const_iterator it = ipLoginMap.find(clientIp); return it != ipLoginMap.end() && it->second.lastProtocol != protocolId && it->second.loginsAmount > maxLoginTries && (int32_t)time(NULL) < it->second.lastLogin + g_config.getNumber(ConfigManager::LOGIN_TIMEOUT) / 1000; }
Connection_ptr ConnectionManager::createConnection(boost::asio::ip::tcp::socket* socket, boost::asio::io_service& io_service, ServicePort_ptr servicer) { LOGt("ConnectionManager::createConnection()"); boost::recursive_mutex::scoped_lock lockClass(m_connectionManagerLock); Connection_ptr connection = std::make_shared<Connection>(socket, io_service, servicer); m_connections.push_back(connection); return connection; }
Connection* ConnectionManager::createConnection(boost::asio::io_service& io_service) { #ifdef __DEBUG_NET_DETAIL__ std::clog << "Create new Connection" << std::endl; #endif boost::recursive_mutex::scoped_lock lockClass(m_connectionManagerLock); Connection* connection = new Connection(io_service); m_connections.push_back(connection); return connection; }
void ConnectionManager::releaseConnection(Connection_ptr connection) { boost::recursive_mutex::scoped_lock lockClass(m_connectionManagerLock); std::list<Connection_ptr>::iterator it = std::find(m_connections.begin(), m_connections.end(), connection); if (it != m_connections.end()) { m_connections.erase(it); } else { std::cout << "Error: [ConnectionManager::releaseConnection] Connection not found" << std::endl; } }
void ConnectionManager::releaseConnection(Connection_ptr connection) { LOGt("ConnectionManager::releaseConnection()"); boost::recursive_mutex::scoped_lock lockClass(m_connectionManagerLock); std::list<Connection_ptr>::iterator it =std::find(m_connections.begin(), m_connections.end(), connection); if(it != m_connections.end()) m_connections.erase(it); else LOGe("[ConnectionManager::releaseConnection] Connection not found"); }
Connection_ptr ConnectionManager::createConnection(boost::asio::ip::tcp::socket* socket, boost::asio::io_service& io_service, ServicePort_ptr servicer) { #ifdef __DEBUG_NET_DETAIL__ std::cout << "Create new Connection" << std::endl; #endif boost::recursive_mutex::scoped_lock lockClass(m_connectionManagerLock); Connection_ptr connection = boost::shared_ptr<Connection>(new Connection(socket, io_service, servicer)); m_connections.push_back(connection); return connection; }
void OutputMessagePool::sendAll() { OTSYS_THREAD_LOCK_CLASS lockClass(m_outputPoolLock); OutputMessageList::iterator it; for(it = m_toAddQueue.begin(); it != m_toAddQueue.end();) { //drop messages that are older than 10 seconds if(OTSYS_TIME() - (*it)->getFrame() > 10000) { if((*it)->getProtocol()) (*it)->getProtocol()->onSendMessage(*it); it = m_toAddQueue.erase(it); continue; } (*it)->setState(OutputMessage::STATE_ALLOCATED); m_autoSendOutputMessages.push_back(*it); ++it; } m_toAddQueue.clear(); for(it = m_autoSendOutputMessages.begin(); it != m_autoSendOutputMessages.end(); ) { OutputMessage_ptr omsg = (*it); #ifdef __NO_PLAYER_SENDBUFFER__ //use this define only for debugging if(true) #else //It will send only messages bigger then 1 kb or with a lifetime greater than 10 ms if(omsg->getMessageLength() > 1024 || (m_frameTime - omsg->getFrame() > 10)) #endif { #ifdef __DEBUG_NET_DETAIL__ std::cout << "Sending message - ALL" << std::endl; #endif if(omsg->getConnection()) { if(!omsg->getConnection()->send(omsg) && omsg->getProtocol()) omsg->getProtocol()->onSendMessage(omsg); } #ifdef __DEBUG_NET__ else std::cout << "Error: [OutputMessagePool::send] NULL connection." << std::endl; #endif it = m_autoSendOutputMessages.erase(it); } else ++it; } }
void ConnectionManager::releaseConnection(Connection_ptr connection) { #ifdef __DEBUG_NET_DETAIL__ std::clog << "Releasing connection" << std::endl; #endif boost::recursive_mutex::scoped_lock lockClass(m_connectionManagerLock); std::list<Connection_ptr>::iterator it = std::find(m_connections.begin(), m_connections.end(), connection); if(it != m_connections.end()) m_connections.erase(it); else std::clog << "[Error - ConnectionManager::releaseConnection] Connection not found" << std::endl; }
void Connection::close() { //any thread #ifdef __DEBUG_NET_DETAIL__ std::clog << "Connection::close" << std::endl; #endif boost::recursive_mutex::scoped_lock lockClass(m_connectionLock); if(m_connectionState == CONNECTION_STATE_CLOSED || m_connectionState == CONNECTION_STATE_REQUEST_CLOSE) return; m_connectionState = CONNECTION_STATE_REQUEST_CLOSE; Dispatcher::getInstance().addTask(createTask(boost::bind(&Connection::closeConnection, this))); }
void Connection::send(const OutputMessage_ptr& msg) { std::lock_guard<std::recursive_mutex> lockClass(connectionLock); if (connectionState != CONNECTION_STATE_OPEN) { return; } bool noPendingWrite = messageQueue.empty(); messageQueue.emplace_back(msg); if (noPendingWrite) { internalSend(msg); } }
uint32_t Connection::getIP() { std::lock_guard<std::recursive_mutex> lockClass(connectionLock); // IP-address is expressed in network byte order boost::system::error_code error; const boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(error); if (error) { return 0; } return htonl(endpoint.address().to_v4().to_ulong()); }
void Connection::closeConnection() { //any thread std::lock_guard<std::recursive_mutex> lockClass(m_connectionLock); if (m_connectionState == CONNECTION_STATE_CLOSING || m_connectionState == CONNECTION_STATE_CLOSED || m_connectionState == CONNECTION_STATE_REQUEST_CLOSE) { return; } m_connectionState = CONNECTION_STATE_REQUEST_CLOSE; g_dispatcher.addTask( createTask(std::bind(&Connection::closeConnectionTask, this))); }
void ConnectionManager::closeAll() { std::lock_guard<std::recursive_mutex> lockClass(m_connectionManagerLock); for (const Connection_ptr& connection : m_connections) { try { boost::system::error_code error; connection->m_socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, error); connection->m_socket->close(error); } catch (boost::system::system_error&) { } } m_connections.clear(); }