Exemple #1
0
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);
	}
}
Exemple #4
0
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();
}
Exemple #5
0
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();
	}
}