void ProtocolGameBase::onConnect() { auto output = OutputMessagePool::getOutputMessage(); static std::random_device rd; static std::ranlux24 generator(rd()); static std::uniform_int_distribution<uint16_t> randNumber(0x00, 0xFF); // Skip checksum output->skipBytes(sizeof(uint32_t)); // Packet length & type output->add<uint16_t>(0x0006); output->addByte(0x1F); // Add timestamp & random number m_challengeTimestamp = static_cast<uint32_t>(time(nullptr)); output->add<uint32_t>(m_challengeTimestamp); m_challengeRandom = randNumber(generator); output->addByte(m_challengeRandom); // Go back and write checksum output->skipBytes(-12); output->add<uint32_t>(adlerChecksum(output->getOutputBuffer() + sizeof(uint32_t), 8)); send(std::move(output)); }
void Connection::parsePacket(const boost::system::error_code& error) { m_connectionLock.lock(); m_readTimer.cancel(); if (error) { handleReadError(error); } if (m_connectionState != CONNECTION_STATE_OPEN || m_readError) { closeConnection(); m_connectionLock.unlock(); return; } uint32_t timePassed = std::max<uint32_t>(1, (time(nullptr) - m_timeConnected) + 1); if ((++m_packetsSent / timePassed) > (uint32_t)g_config.getNumber(ConfigManager::MAX_PACKETS_PER_SECOND)) { std::cout << convertIPToString(getIP()) << " disconnected for exceeding packet per second limit." << std::endl; closeConnection(); m_connectionLock.unlock(); return; } if (timePassed > 2) { m_timeConnected = time(nullptr); m_packetsSent = 0; } //Check packet checksum uint32_t checksum; int32_t len = m_msg.getMessageLength() - m_msg.getReadPos() - 4; if (len > 0) { checksum = adlerChecksum(m_msg.getBuffer() + m_msg.getReadPos() + 4, len); } else { checksum = 0; } uint32_t recvChecksum = m_msg.get<uint32_t>(); if (recvChecksum != checksum) { // it might not have been the checksum, step back m_msg.SkipBytes(-4); } if (!m_receivedFirst) { // First message received m_receivedFirst = true; if (!m_protocol) { // Game protocol has already been created at this point m_protocol = m_service_port->make_protocol(recvChecksum == checksum, m_msg); if (!m_protocol) { closeConnection(); m_connectionLock.unlock(); return; } m_protocol->setConnection(shared_from_this()); } else { m_msg.GetByte(); // Skip protocol ID } m_protocol->onRecvFirstMessage(m_msg); } else { m_protocol->onRecvMessage(m_msg); // Send the packet to the current protocol } try { m_readTimer.expires_from_now(boost::posix_time::seconds(Connection::read_timeout)); m_readTimer.async_wait( std::bind(&Connection::handleReadTimeout, std::weak_ptr<Connection>(shared_from_this()), std::placeholders::_1)); // Wait to the next packet boost::asio::async_read(getHandle(), boost::asio::buffer(m_msg.getBuffer(), NetworkMessage::header_length), std::bind(&Connection::parseHeader, shared_from_this(), std::placeholders::_1)); } catch (boost::system::system_error& e) { if (m_logError) { std::cout << "[Network error - Connection::parsePacket] " << e.what() << std::endl; m_logError = false; } closeConnection(); } m_connectionLock.unlock(); }
void Connection::parsePacket(const boost::system::error_code& error) { std::lock_guard<std::recursive_mutex> lockClass(connectionLock); readTimer.cancel(); if (error) { close(FORCE_CLOSE); } if (connectionState != CONNECTION_STATE_OPEN) { return; } //Check packet checksum uint32_t checksum; int32_t len = msg.getLength() - msg.getBufferPosition() - NetworkMessage::CHECKSUM_LENGTH; if (len > 0) { checksum = adlerChecksum(msg.getBuffer() + msg.getBufferPosition() + NetworkMessage::CHECKSUM_LENGTH, len); } else { checksum = 0; } uint32_t recvChecksum = msg.get<uint32_t>(); if (recvChecksum != checksum) { // it might not have been the checksum, step back msg.skipBytes(-NetworkMessage::CHECKSUM_LENGTH); } if (!receivedFirst) { // First message received receivedFirst = true; if (!protocol) { // Game protocol has already been created at this point protocol = service_port->make_protocol(recvChecksum == checksum, msg, shared_from_this()); if (!protocol) { close(FORCE_CLOSE); return; } } else { msg.skipBytes(1); // Skip protocol ID } protocol->onRecvFirstMessage(msg); } else { protocol->onRecvMessage(msg); // Send the packet to the current protocol } try { readTimer.expires_from_now(boost::posix_time::seconds(Connection::read_timeout)); readTimer.async_wait(std::bind(&Connection::handleTimeout, std::weak_ptr<Connection>(shared_from_this()), std::placeholders::_1)); // Wait to the next packet boost::asio::async_read(socket, boost::asio::buffer(msg.getBuffer(), NetworkMessage::HEADER_LENGTH), std::bind(&Connection::parseHeader, shared_from_this(), std::placeholders::_1)); } catch (boost::system::system_error& e) { std::cout << "[Network error - Connection::parsePacket] " << e.what() << std::endl; close(FORCE_CLOSE); } }
void Connection::parsePacket(const boost::system::error_code& error) { m_connectionLock.lock(); m_readTimer.cancel(); if(error) handleReadError(error); if(m_connectionState != CONNECTION_STATE_OPEN || m_readError) { close(); m_connectionLock.unlock(); return; } --m_pendingRead; uint32_t length = m_msg.size() - m_msg.position() - 4, checksumReceived = m_msg.get<uint32_t>(true), checksum = 0; if(length > 0) checksum = adlerChecksum((uint8_t*)(m_msg.buffer() + m_msg.position() + 4), length); bool checksumEnabled = false; if(checksumReceived == checksum) { m_msg.skip(4); checksumEnabled = true; } if(!m_receivedFirst) { // First message received m_receivedFirst = true; if(!m_protocol) { // Game protocol has already been created at this point m_protocol = m_servicePort->makeProtocol(checksumEnabled, m_msg); if(!m_protocol) { close(); m_connectionLock.unlock(); return; } m_protocol->setConnection(shared_from_this()); } else m_msg.skip(1); // Skip protocol m_protocol->onRecvFirstMessage(m_msg); } else m_protocol->onRecvMessage(m_msg); // Send the packet to the current protocol try { ++m_pendingRead; m_readTimer.expires_from_now(boost::posix_time::seconds(Connection::readTimeout)); m_readTimer.async_wait(boost::bind(&Connection::handleReadTimeout, boost::weak_ptr<Connection>(shared_from_this()), boost::asio::placeholders::error)); // Wait to the next packet boost::asio::async_read(getHandle(), boost::asio::buffer(m_msg.buffer(), NETWORK_HEADER_SIZE), boost::bind(&Connection::parseHeader, shared_from_this(), boost::asio::placeholders::error)); } catch(boost::system::system_error& e) { if(m_logError) { LOG_MESSAGE(LOGTYPE_ERROR, e.what(), "NETWORK"); m_logError = false; close(); } } m_connectionLock.unlock(); }
void Connection::parsePacket(const boost::system::error_code& error) { m_connectionLock.lock(); m_readTimer.cancel(); if(error){ handleReadError(error); } if(m_connectionState != CONNECTION_STATE_OPEN || m_readError){ closeConnection(); m_connectionLock.unlock(); return; } --m_pendingRead; //Check packet checksum uint32_t recvChecksum = m_msg.PeekU32(); uint32_t checksum = 0; int32_t len = m_msg.getMessageLength() - m_msg.getReadPos() - 4; if(len > 0){ checksum = adlerChecksum((uint8_t*)(m_msg.getBuffer() + m_msg.getReadPos() + 4), len); } if(recvChecksum == checksum) // remove the checksum m_msg.GetU32(); if(!m_receivedFirst){ m_receivedFirst = true; // First message received if(!m_protocol){ // Game protocol has already been created at this point m_protocol = m_service_port->make_protocol(recvChecksum == checksum, m_msg); if(!m_protocol){ closeConnection(); m_connectionLock.unlock(); return; } m_protocol->setConnection(shared_from_this()); } else{ // Skip protocol ID m_msg.GetByte(); } m_protocol->onRecvFirstMessage(m_msg); } else{ // Send the packet to the current protocol m_protocol->onRecvMessage(m_msg); } try{ ++m_pendingRead; m_readTimer.expires_from_now(boost::posix_time::seconds(Connection::read_timeout)); m_readTimer.async_wait( boost::bind(&Connection::handleReadTimeout, boost::weak_ptr<Connection>(shared_from_this()), boost::asio::placeholders::error)); // Wait to the next packet boost::asio::async_read(getHandle(), boost::asio::buffer(m_msg.getBuffer(), NetworkMessage::header_length), boost::bind(&Connection::parseHeader, shared_from_this(), boost::asio::placeholders::error)); } catch(boost::system::system_error& e){ if(m_logError){ LOG_MESSAGE("NETWORK", LOGTYPE_ERROR, 1, e.what()); m_logError = false; closeConnection(); } } m_connectionLock.unlock(); }
void Connection::parsePacket(const boost::system::error_code& error) { std::lock_guard<std::recursive_mutex> lockClass(m_connectionLock); m_readTimer.cancel(); if (error) { handleReadError(error); } if (m_connectionState != CONNECTION_STATE_OPEN || m_readError) { close(); return; } //Check packet checksum uint32_t checksum; int32_t len = m_msg.getLength() - m_msg.getBufferPosition() - 4; if (len > 0) { checksum = adlerChecksum(m_msg.getBuffer() + m_msg.getBufferPosition() + 4, len); } else { checksum = 0; } uint32_t recvChecksum = m_msg.get<uint32_t>(); if (recvChecksum != checksum) { // it might not have been the checksum, step back m_msg.skipBytes(-4); } if (!m_receivedFirst) { // First message received m_receivedFirst = true; if (!m_protocol) { // Game protocol has already been created at this point m_protocol = m_service_port->make_protocol(recvChecksum == checksum, m_msg); if (!m_protocol) { close(); return; } m_protocol->setConnection(shared_from_this()); } else { m_msg.getByte(); // Skip protocol ID } m_protocol->onRecvFirstMessage(m_msg); } else { m_protocol->onRecvMessage(m_msg); // Send the packet to the current protocol } try { m_readTimer.expires_from_now(boost::posix_time::seconds(Connection::read_timeout)); m_readTimer.async_wait( std::bind(&Connection::handleReadTimeout, std::weak_ptr<Connection>(shared_from_this()), std::placeholders::_1)); // Wait to the next packet boost::asio::async_read(getHandle(), boost::asio::buffer(m_msg.getBuffer(), NetworkMessage::header_length), std::bind(&Connection::parseHeader, shared_from_this(), std::placeholders::_1)); } catch (boost::system::system_error& e) { if (m_logError) { std::cout << "[Network error - Connection::parsePacket] " << e.what() << std::endl; m_logError = false; } close(); } }