Fix PACKET_SERVER_MAP_DONE prepending with packet encryption

Also fix logging of sent encrypted packets
This commit is contained in:
Jonathan G Rennison
2024-07-03 02:32:57 +01:00
parent 06718b632d
commit 7c569b2c83
5 changed files with 42 additions and 15 deletions

View File

@@ -54,12 +54,16 @@ Packet::Packet(NetworkSocketHandler *cs, PacketType type, size_t limit) : pos(0)
void Packet::ResetState(PacketType type) void Packet::ResetState(PacketType type)
{ {
this->buffer.clear(); this->buffer.clear();
this->tx_packet_type = type;
/* Allocate space for the the size so we can write that in just before sending the packet. */ /* Allocate space for the the size so we can write that in just before sending the packet. */
size_t size = EncodedLengthOfPacketSize(); size_t size = EncodedLengthOfPacketSize();
if (cs != nullptr && cs->send_encryption_handler != nullptr) { if (cs != nullptr && cs->send_encryption_handler != nullptr) {
/* Allocate some space for the message authentication code of the encryption. */ /* Allocate some space for the message authentication code of the encryption. */
size += cs->send_encryption_handler->MACSize(); size += cs->send_encryption_handler->MACSize();
this->encyption_pending = true;
} else {
this->encyption_pending = false;
} }
assert(this->CanWriteToPacket(size)); assert(this->CanWriteToPacket(size));
this->buffer.resize(size, 0); this->buffer.resize(size, 0);
@@ -70,7 +74,7 @@ void Packet::ResetState(PacketType type)
/** /**
* Writes the packet size from the raw packet from packet->size * Writes the packet size from the raw packet from packet->size
*/ */
void Packet::PrepareToSend() void Packet::PrepareForSendQueue()
{ {
/* Prevent this to be called twice and for packets that have been received. */ /* Prevent this to be called twice and for packets that have been received. */
assert(this->buffer[0] == 0 && this->buffer[1] == 0); assert(this->buffer[0] == 0 && this->buffer[1] == 0);
@@ -78,15 +82,17 @@ void Packet::PrepareToSend()
this->buffer[0] = GB(this->Size(), 0, 8); this->buffer[0] = GB(this->Size(), 0, 8);
this->buffer[1] = GB(this->Size(), 8, 8); this->buffer[1] = GB(this->Size(), 8, 8);
if (cs != nullptr && cs->send_encryption_handler != nullptr) { this->pos = 0; // We start reading from here
this->buffer.shrink_to_fit();
}
void Packet::PreSendEncryption()
{
this->encyption_pending = false;
size_t offset = EncodedLengthOfPacketSize(); size_t offset = EncodedLengthOfPacketSize();
size_t mac_size = cs->send_encryption_handler->MACSize(); size_t mac_size = cs->send_encryption_handler->MACSize();
size_t message_offset = offset + mac_size; size_t message_offset = offset + mac_size;
cs->send_encryption_handler->Encrypt(std::span(&this->buffer[offset], mac_size), std::span(&this->buffer[message_offset], this->buffer.size() - message_offset)); cs->send_encryption_handler->Encrypt(std::span(&this->buffer[offset], mac_size), std::span(&this->buffer[message_offset], this->buffer.size() - message_offset));
}
this->pos = 0; // We start reading from here
this->buffer.shrink_to_fit();
} }
/** /**

View File

@@ -51,6 +51,10 @@ struct Packet : public BufferSerialisationHelper<Packet>, public BufferDeseriali
private: private:
/** The current read/write position in the packet */ /** The current read/write position in the packet */
PacketSize pos; PacketSize pos;
/** Whether encryption is required for this packet */
bool encyption_pending = false;
/** Packet type, for transmitted packets */
PacketType tx_packet_type;
/** The buffer of this packet. */ /** The buffer of this packet. */
std::vector<uint8_t> buffer; std::vector<uint8_t> buffer;
/** The limit for the packet size. */ /** The limit for the packet size. */
@@ -59,6 +63,8 @@ private:
/** Socket we're associated with. */ /** Socket we're associated with. */
NetworkSocketHandler *cs; NetworkSocketHandler *cs;
void PreSendEncryption();
public: public:
struct ReadTag{}; struct ReadTag{};
Packet(ReadTag tag, NetworkSocketHandler *cs, size_t limit, size_t initial_read_size = EncodedLengthOfPacketSize()); Packet(ReadTag tag, NetworkSocketHandler *cs, size_t limit, size_t initial_read_size = EncodedLengthOfPacketSize());
@@ -66,8 +72,21 @@ public:
void ResetState(PacketType type); void ResetState(PacketType type);
void PrepareForSendQueue();
inline void CheckPendingPreSendEncryption()
{
if (this->encyption_pending) {
this->PreSendEncryption();
}
}
/* Sending/writing of packets */ /* Sending/writing of packets */
void PrepareToSend(); inline void PrepareToSend()
{
this->PrepareForSendQueue();
this->CheckPendingPreSendEncryption();
}
std::vector<uint8_t> &GetSerialisationBuffer() { return this->buffer; } std::vector<uint8_t> &GetSerialisationBuffer() { return this->buffer; }
size_t GetSerialisationLimit() const { return this->limit; } size_t GetSerialisationLimit() const { return this->limit; }
@@ -88,6 +107,7 @@ public:
size_t Size() const; size_t Size() const;
[[nodiscard]] bool PrepareToRead(); [[nodiscard]] bool PrepareToRead();
PacketType GetPacketType() const; PacketType GetPacketType() const;
PacketType GetTransmitPacketType() const { return this->tx_packet_type; }
bool CanReadFromPacket(size_t bytes_to_read, bool close_connection = false); bool CanReadFromPacket(size_t bytes_to_read, bool close_connection = false);

View File

@@ -69,7 +69,7 @@ void NetworkTCPSocketHandler::SendPacket(std::unique_ptr<Packet> packet)
{ {
assert(packet != nullptr); assert(packet != nullptr);
packet->PrepareToSend(); packet->PrepareForSendQueue();
this->packet_queue.push_back(std::move(packet)); this->packet_queue.push_back(std::move(packet));
} }
@@ -84,11 +84,11 @@ void NetworkTCPSocketHandler::SendPrependPacket(std::unique_ptr<Packet> packet,
{ {
assert(packet != nullptr); assert(packet != nullptr);
packet->PrepareToSend(); packet->PrepareForSendQueue();
if (queue_after_packet_type >= 0) { if (queue_after_packet_type >= 0) {
for (auto iter = this->packet_queue.begin(); iter != this->packet_queue.end(); ++iter) { for (auto iter = this->packet_queue.begin(); iter != this->packet_queue.end(); ++iter) {
if ((*iter)->GetPacketType() == queue_after_packet_type) { if ((*iter)->GetTransmitPacketType() == queue_after_packet_type) {
++iter; ++iter;
this->packet_queue.insert(iter, std::move(packet)); this->packet_queue.insert(iter, std::move(packet));
return; return;
@@ -131,6 +131,7 @@ SendPacketsState NetworkTCPSocketHandler::SendPackets(bool closing_down)
while (!this->packet_queue.empty()) { while (!this->packet_queue.empty()) {
Packet &p = *this->packet_queue.front(); Packet &p = *this->packet_queue.front();
p.CheckPendingPreSendEncryption();
ssize_t res = p.TransferOut<int>(send, this->sock, 0); ssize_t res = p.TransferOut<int>(send, this->sock, 0);
if (res == -1) { if (res == -1) {
NetworkError err = NetworkError::GetLast(); NetworkError err = NetworkError::GetLast();

View File

@@ -295,7 +295,7 @@ std::string NetworkGameSocketHandler::GetDebugInfo() const { return ""; }
void NetworkGameSocketHandler::LogSentPacket(const Packet &pkt) void NetworkGameSocketHandler::LogSentPacket(const Packet &pkt)
{ {
PacketGameType type = (PacketGameType)pkt.GetPacketType(); PacketGameType type = (PacketGameType)pkt.GetTransmitPacketType();
DEBUG(net, 5, "[tcp/game] sent packet type %d (%s) to client %d, %s", type, GetPacketGameTypeName(type), this->client_id, this->GetDebugInfo().c_str()); DEBUG(net, 5, "[tcp/game] sent packet type %d (%s) to client %d, %s", type, GetPacketGameTypeName(type), this->client_id, this->GetDebugInfo().c_str());
} }

View File

@@ -136,7 +136,7 @@ struct PacketWriter : SaveFilter {
} }
bool last_packet = false; bool last_packet = false;
for (auto &p : this->packets) { for (auto &p : this->packets) {
if (p->GetPacketType() == PACKET_SERVER_MAP_DONE) last_packet = true; if (p->GetTransmitPacketType() == PACKET_SERVER_MAP_DONE) last_packet = true;
this->cs->SendPacket(std::move(p)); this->cs->SendPacket(std::move(p));
} }