Changeset - r25242:16241601aa3b
[Not reviewed]
master
0 4 0
Rubidium - 3 years ago 2021-04-18 07:01:27
rubidium@openttd.org
Codechange: move more logic about packet size validity and reading into Packet
4 files changed with 29 insertions and 13 deletions:
0 comments (0 inline, 0 general)
src/network/core/packet.cpp
Show inline comments
 
@@ -178,28 +178,45 @@ bool Packet::CanReadFromPacket(uint byte
 
	}
 

	
 
	return true;
 
}
 

	
 
/**
 
 * Reads the packet size from the raw packet and stores it in the packet->size
 
 * Check whether the packet, given the position of the "write" pointer, has read
 
 * enough of the packet to contain its size.
 
 * @return True iff there is enough data in the packet to contain the packet's size.
 
 */
 
void Packet::ReadRawPacketSize()
 
bool Packet::HasPacketSizeData() const
 
{
 
	return this->pos >= sizeof(PacketSize);
 
}
 

	
 
/**
 
 * Reads the packet size from the raw packet and stores it in the packet->size
 
 * @return True iff the packet size seems plausible.
 
 */
 
bool Packet::ParsePacketSize()
 
{
 
	assert(this->cs != nullptr && this->next == nullptr);
 
	this->size  = (PacketSize)this->buffer[0];
 
	this->size += (PacketSize)this->buffer[1] << 8;
 

	
 
	/* If the size of the packet is less than the bytes required for the size and type of
 
	 * the packet, or more than the allowed limit, then something is wrong with the packet.
 
	 * In those cases the packet can generally be regarded as containing garbage data. */
 
	if (this->size < sizeof(PacketSize) + sizeof(PacketType) || this->size > SEND_MTU) return false;
 

	
 
	this->pos = sizeof(PacketSize);
 
	return true;
 
}
 

	
 
/**
 
 * Prepares the packet so it can be read
 
 */
 
void Packet::PrepareToRead()
 
{
 
	this->ReadRawPacketSize();
 

	
 
	/* Put the position on the right place */
 
	this->pos = sizeof(PacketSize);
 
}
 

	
 
/**
 
 * Read a boolean from the packet.
src/network/core/packet.h
Show inline comments
 
@@ -68,13 +68,14 @@ public:
 
	void Send_uint16(uint16 data);
 
	void Send_uint32(uint32 data);
 
	void Send_uint64(uint64 data);
 
	void Send_string(const char *data);
 

	
 
	/* Reading/receiving of packets */
 
	void ReadRawPacketSize();
 
	bool HasPacketSizeData() const;
 
	bool ParsePacketSize();
 
	void PrepareToRead();
 

	
 
	bool   CanReadFromPacket (uint bytes_to_read);
 
	bool   Recv_bool  ();
 
	uint8  Recv_uint8 ();
 
	uint16 Recv_uint16();
src/network/core/tcp.cpp
Show inline comments
 
@@ -152,14 +152,14 @@ Packet *NetworkTCPSocketHandler::Receive
 
		this->packet_recv = new Packet(this);
 
	}
 

	
 
	Packet *p = this->packet_recv;
 

	
 
	/* Read packet size */
 
	if (p->pos < sizeof(PacketSize)) {
 
		while (p->pos < sizeof(PacketSize)) {
 
	if (!p->HasPacketSizeData()) {
 
		while (!p->HasPacketSizeData()) {
 
		/* Read the size of the packet */
 
			res = recv(this->sock, (char*)p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0);
 
			if (res == -1) {
 
				int err = GET_LAST_ERROR();
 
				if (err != EWOULDBLOCK) {
 
					/* Something went wrong... (104 is connection reset by peer) */
 
@@ -175,16 +175,14 @@ Packet *NetworkTCPSocketHandler::Receive
 
				this->CloseConnection();
 
				return nullptr;
 
			}
 
			p->pos += res;
 
		}
 

	
 
		/* Read the packet size from the received packet */
 
		p->ReadRawPacketSize();
 

	
 
		if (p->size > SEND_MTU) {
 
		/* Parse the size in the received packet and if not valid, close the connection. */
 
		if (!p->ParsePacketSize()) {
 
			this->CloseConnection();
 
			return nullptr;
 
		}
 
	}
 

	
 
	/* Read rest of packet */
src/network/core/udp.cpp
Show inline comments
 
@@ -131,20 +131,20 @@ void NetworkUDPSocketHandler::ReceivePac
 
			if (nbytes <= 2) continue; // Invalid data; try next packet
 
#ifdef __EMSCRIPTEN__
 
			client_len = FixAddrLenForEmscripten(client_addr);
 
#endif
 

	
 
			NetworkAddress address(client_addr, client_len);
 
			p.PrepareToRead();
 

	
 
			/* If the size does not match the packet must be corrupted.
 
			 * Otherwise it will be marked as corrupted later on. */
 
			if (nbytes != p.size) {
 
			if (!p.ParsePacketSize() || nbytes != p.size) {
 
				DEBUG(net, 1, "received a packet with mismatching size from %s", address.GetAddressAsString().c_str());
 
				continue;
 
			}
 
			p.PrepareToRead();
 

	
 
			/* Handle the packet */
 
			this->HandleUDPPacket(&p, &address);
 
		}
 
	}
 
}
0 comments (0 inline, 0 general)