From 8b302761d4ca51f41eaff4097c9afa4f3aec5ec5 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sun, 18 Apr 2021 14:42:06 +0200 Subject: [PATCH] Codechange: allow different limits in packet sizes --- src/network/core/packet.cpp | 17 +++++++++++------ src/network/core/packet.h | 15 +++++++++------ src/network/core/tcp.cpp | 2 +- src/network/core/udp.cpp | 3 ++- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/network/core/packet.cpp b/src/network/core/packet.cpp index 428bc65ba4..39531c0a40 100644 --- a/src/network/core/packet.cpp +++ b/src/network/core/packet.cpp @@ -19,6 +19,7 @@ /** * Create a packet that is used to read from a network socket. * @param cs The socket handler associated with the socket we are reading from. + * @param limit The maximum size of packets to accept. * @param initial_read_size The initial amount of data to transfer from the socket into the * packet. This defaults to just the required bytes to determine the * packet's size. That default is the wanted for streams such as TCP @@ -27,7 +28,7 @@ * loose some the data of the packet, so there you pass the maximum * size for the packet you expect from the network. */ -Packet::Packet(NetworkSocketHandler *cs, size_t initial_read_size) : next(nullptr), pos(0) +Packet::Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size) : next(nullptr), pos(0), limit(limit) { assert(cs != nullptr); @@ -37,9 +38,13 @@ Packet::Packet(NetworkSocketHandler *cs, size_t initial_read_size) : next(nullpt /** * Creates a packet to send - * @param type of the packet to send + * @param type The type of the packet to send + * @param limit The maximum number of bytes the packet may have. Default is SEND_MTU. + * Be careful of compatibility with older clients/servers when changing + * the limit as it might break things if the other side is not expecting + * much larger packets than what they support. */ -Packet::Packet(PacketType type) : next(nullptr), pos(0), cs(nullptr) +Packet::Packet(PacketType type, size_t limit) : next(nullptr), pos(0), cs(nullptr) { /* Allocate space for the the size so we can write that in just before sending the packet. */ this->Send_uint16(0); @@ -93,7 +98,7 @@ void Packet::PrepareToSend() */ bool Packet::CanWriteToPacket(size_t bytes_to_write) { - return this->Size() + bytes_to_write < SEND_MTU; + return this->Size() + bytes_to_write < this->limit; } /* @@ -191,7 +196,7 @@ void Packet::Send_string(const char *data) */ size_t Packet::Send_bytes(const byte *begin, const byte *end) { - size_t amount = std::min(end - begin, SEND_MTU - this->Size()); + size_t amount = std::min(end - begin, this->limit - this->Size()); this->buffer.insert(this->buffer.end(), begin, begin + amount); return amount; } @@ -260,7 +265,7 @@ bool Packet::ParsePacketSize() /* 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 (size < sizeof(PacketSize) + sizeof(PacketType) || size > SEND_MTU) return false; + if (size < sizeof(PacketSize) + sizeof(PacketType) || size > this->limit) return false; this->buffer.resize(size); this->pos = sizeof(PacketSize); diff --git a/src/network/core/packet.h b/src/network/core/packet.h index 1ac7f18a18..db051005c5 100644 --- a/src/network/core/packet.h +++ b/src/network/core/packet.h @@ -25,10 +25,11 @@ typedef uint8 PacketType; ///< Identifier for the packet * Internal entity of a packet. As everything is sent as a packet, * all network communication will need to call the functions that * populate the packet. - * Every packet can be at most SEND_MTU bytes. Overflowing this - * limit will give an assertion when sending (i.e. writing) the - * packet. Reading past the size of the packet when receiving - * will return all 0 values and "" in case of the string. + * Every packet can be at most a limited number bytes set in the + * constructor. Overflowing this limit will give an assertion when + * sending (i.e. writing) the packet. Reading past the size of the + * packet when receiving will return all 0 values and "" in case of + * the string. * * --- Points of attention --- * - all > 1 byte integral values are written in little endian, @@ -47,13 +48,15 @@ private: PacketSize pos; /** The buffer of this packet. */ std::vector buffer; + /** The limit for the packet size. */ + size_t limit; /** Socket we're associated with. */ NetworkSocketHandler *cs; public: - Packet(NetworkSocketHandler *cs, size_t initial_read_size = sizeof(PacketSize)); - Packet(PacketType type); + Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size = sizeof(PacketSize)); + Packet(PacketType type, size_t limit = SEND_MTU); static void AddToQueue(Packet **queue, Packet *packet); static Packet *PopFromQueue(Packet **queue); diff --git a/src/network/core/tcp.cpp b/src/network/core/tcp.cpp index a749b6195b..be70efdd2f 100644 --- a/src/network/core/tcp.cpp +++ b/src/network/core/tcp.cpp @@ -126,7 +126,7 @@ Packet *NetworkTCPSocketHandler::ReceivePacket() if (!this->IsConnected()) return nullptr; if (this->packet_recv == nullptr) { - this->packet_recv = new Packet(this); + this->packet_recv = new Packet(this, SEND_MTU); } Packet *p = this->packet_recv; diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp index 3bd2151fe1..8872fa295a 100644 --- a/src/network/core/udp.cpp +++ b/src/network/core/udp.cpp @@ -119,7 +119,8 @@ void NetworkUDPSocketHandler::ReceivePackets() struct sockaddr_storage client_addr; memset(&client_addr, 0, sizeof(client_addr)); - Packet p(this, SEND_MTU); + /* The limit is SEND_MTU, but also allocate that much as we need to read the whole packet in one go. */ + Packet p(this, SEND_MTU, SEND_MTU); socklen_t client_len = sizeof(client_addr); /* Try to receive anything */