diff --git a/src/network/core/packet.cpp b/src/network/core/packet.cpp --- a/src/network/core/packet.cpp +++ b/src/network/core/packet.cpp @@ -27,39 +27,23 @@ * 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) +Packet::Packet(NetworkSocketHandler *cs, size_t initial_read_size) : next(nullptr), pos(0) { assert(cs != nullptr); - this->cs = cs; - this->next = nullptr; - this->pos = 0; // We start reading from here - this->size = static_cast(initial_read_size); - this->buffer = MallocT(SEND_MTU); + this->cs = cs; + this->buffer.resize(initial_read_size); } /** * Creates a packet to send * @param type of the packet to send */ -Packet::Packet(PacketType type) +Packet::Packet(PacketType type) : next(nullptr), pos(0), cs(nullptr) { - this->cs = nullptr; - this->next = nullptr; - - /* Skip the size so we can write that in before sending the packet */ - this->pos = 0; - this->size = sizeof(PacketSize); - this->buffer = MallocT(SEND_MTU); - this->buffer[this->size++] = type; -} - -/** - * Free the buffer of this packet. - */ -Packet::~Packet() -{ - free(this->buffer); + /* Allocate space for the the size so we can write that in just before sending the packet. */ + this->Send_uint16(0); + this->Send_uint8(type); } /** @@ -95,15 +79,11 @@ void Packet::PrepareToSend() { assert(this->cs == nullptr && this->next == nullptr); - this->buffer[0] = GB(this->size, 0, 8); - this->buffer[1] = GB(this->size, 8, 8); + this->buffer[0] = GB(this->Size(), 0, 8); + this->buffer[1] = GB(this->Size(), 8, 8); this->pos = 0; // We start reading from here - - /* Reallocate the packet as in 99+% of the times we send at most 25 bytes and - * keeping the other 1400+ bytes wastes memory, especially when someone tries - * to do a denial of service attack! */ - this->buffer = ReallocT(this->buffer, this->size); + this->buffer.shrink_to_fit(); } /** @@ -113,7 +93,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 < SEND_MTU; } /* @@ -144,7 +124,7 @@ void Packet::Send_bool(bool data) void Packet::Send_uint8(uint8 data) { assert(this->CanWriteToPacket(sizeof(data))); - this->buffer[this->size++] = data; + this->buffer.emplace_back(data); } /** @@ -154,8 +134,8 @@ void Packet::Send_uint8(uint8 data) void Packet::Send_uint16(uint16 data) { assert(this->CanWriteToPacket(sizeof(data))); - this->buffer[this->size++] = GB(data, 0, 8); - this->buffer[this->size++] = GB(data, 8, 8); + this->buffer.emplace_back(GB(data, 0, 8)); + this->buffer.emplace_back(GB(data, 8, 8)); } /** @@ -165,10 +145,10 @@ void Packet::Send_uint16(uint16 data) void Packet::Send_uint32(uint32 data) { assert(this->CanWriteToPacket(sizeof(data))); - this->buffer[this->size++] = GB(data, 0, 8); - this->buffer[this->size++] = GB(data, 8, 8); - this->buffer[this->size++] = GB(data, 16, 8); - this->buffer[this->size++] = GB(data, 24, 8); + this->buffer.emplace_back(GB(data, 0, 8)); + this->buffer.emplace_back(GB(data, 8, 8)); + this->buffer.emplace_back(GB(data, 16, 8)); + this->buffer.emplace_back(GB(data, 24, 8)); } /** @@ -178,14 +158,14 @@ void Packet::Send_uint32(uint32 data) void Packet::Send_uint64(uint64 data) { assert(this->CanWriteToPacket(sizeof(data))); - this->buffer[this->size++] = GB(data, 0, 8); - this->buffer[this->size++] = GB(data, 8, 8); - this->buffer[this->size++] = GB(data, 16, 8); - this->buffer[this->size++] = GB(data, 24, 8); - this->buffer[this->size++] = GB(data, 32, 8); - this->buffer[this->size++] = GB(data, 40, 8); - this->buffer[this->size++] = GB(data, 48, 8); - this->buffer[this->size++] = GB(data, 56, 8); + this->buffer.emplace_back(GB(data, 0, 8)); + this->buffer.emplace_back(GB(data, 8, 8)); + this->buffer.emplace_back(GB(data, 16, 8)); + this->buffer.emplace_back(GB(data, 24, 8)); + this->buffer.emplace_back(GB(data, 32, 8)); + this->buffer.emplace_back(GB(data, 40, 8)); + this->buffer.emplace_back(GB(data, 48, 8)); + this->buffer.emplace_back(GB(data, 56, 8)); } /** @@ -198,7 +178,7 @@ void Packet::Send_string(const char *dat assert(data != nullptr); /* Length of the string + 1 for the '\0' termination. */ assert(this->CanWriteToPacket(strlen(data) + 1)); - while ((this->buffer[this->size++] = *data++) != '\0') {} + while (this->buffer.emplace_back(*data++) != '\0') {} } /** @@ -211,9 +191,8 @@ void Packet::Send_string(const char *dat */ size_t Packet::Send_bytes(const byte *begin, const byte *end) { - size_t amount = std::min(end - begin, SEND_MTU - this->size); - memcpy(this->buffer + this->size, begin, amount); - this->size += static_cast(amount); + size_t amount = std::min(end - begin, SEND_MTU - this->Size()); + this->buffer.insert(this->buffer.end(), begin, begin + amount); return amount; } @@ -238,7 +217,7 @@ bool Packet::CanReadFromPacket(size_t by if (this->cs->HasClientQuit()) return false; /* Check if variable is within packet-size */ - if (this->pos + bytes_to_read > this->size) { + if (this->pos + bytes_to_read > this->Size()) { if (close_connection) this->cs->NetworkSocketHandler::CloseConnection(); return false; } @@ -265,7 +244,7 @@ bool Packet::HasPacketSizeData() const */ size_t Packet::Size() const { - return this->size; + return this->buffer.size(); } /** @@ -275,14 +254,15 @@ size_t Packet::Size() const bool Packet::ParsePacketSize() { assert(this->cs != nullptr && this->next == nullptr); - this->size = (PacketSize)this->buffer[0]; - this->size += (PacketSize)this->buffer[1] << 8; + size_t size = (size_t)this->buffer[0]; + size += (size_t)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; + if (size < sizeof(PacketSize) + sizeof(PacketType) || size > SEND_MTU) return false; + this->buffer.resize(size); this->pos = sizeof(PacketSize); return true; } @@ -398,13 +378,13 @@ void Packet::Recv_string(char *buffer, s if (cs->HasClientQuit()) return; pos = this->pos; - while (--size > 0 && pos < this->size && (*buffer++ = this->buffer[pos++]) != '\0') {} + while (--size > 0 && pos < this->Size() && (*buffer++ = this->buffer[pos++]) != '\0') {} - if (size == 0 || pos == this->size) { + if (size == 0 || pos == this->Size()) { *buffer = '\0'; /* If size was sooner to zero then the string in the stream * skip till the \0, so than packet can be read out correctly for the rest */ - while (pos < this->size && this->buffer[pos] != '\0') pos++; + while (pos < this->Size() && this->buffer[pos] != '\0') pos++; pos++; } this->pos = pos; @@ -418,5 +398,5 @@ void Packet::Recv_string(char *buffer, s */ size_t Packet::RemainingBytesToTransfer() const { - return this->size - this->pos; + return this->Size() - this->pos; } diff --git a/src/network/core/packet.h b/src/network/core/packet.h --- a/src/network/core/packet.h +++ b/src/network/core/packet.h @@ -43,23 +43,17 @@ struct Packet { private: /** The next packet. Used for queueing packets before sending. */ Packet *next; - /** - * The size of the whole packet for received packets. For packets - * that will be sent, the value is filled in just before the - * actual transmission. - */ - PacketSize size; /** The current read/write position in the packet */ PacketSize pos; - /** The buffer of this packet, of basically variable length up to SEND_MTU. */ - byte *buffer; + /** The buffer of this packet. */ + std::vector buffer; + /** Socket we're associated with. */ NetworkSocketHandler *cs; public: Packet(NetworkSocketHandler *cs, size_t initial_read_size = sizeof(PacketSize)); Packet(PacketType type); - ~Packet(); static void AddToQueue(Packet **queue, Packet *packet); static Packet *PopFromQueue(Packet **queue); @@ -118,7 +112,7 @@ public: assert(this->pos < this->buffer.size()); assert(this->pos + amount <= this->buffer.size()); /* Making buffer a char means casting a lot in the Recv/Send functions. */ - const char *output_buffer = reinterpret_cast(this->buffer + this->pos); + const char *output_buffer = reinterpret_cast(this->buffer.data() + this->pos); ssize_t bytes = transfer_function(destination, output_buffer, static_cast(amount), std::forward(args)...); if (bytes > 0) this->pos += bytes; return bytes; @@ -183,7 +177,7 @@ public: assert(this->pos < this->buffer.size()); assert(this->pos + amount <= this->buffer.size()); /* Making buffer a char means casting a lot in the Recv/Send functions. */ - char *input_buffer = reinterpret_cast(this->buffer + this->pos); + char *input_buffer = reinterpret_cast(this->buffer.data() + this->pos); ssize_t bytes = transfer_function(source, input_buffer, static_cast(amount), std::forward(args)...); if (bytes > 0) this->pos += bytes; return bytes;