Fix PACKET_SERVER_MAP_DONE prepending with packet encryption
Also fix logging of sent encrypted packets
This commit is contained in:
@@ -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,17 +82,19 @@ 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
|
||||||
size_t offset = EncodedLengthOfPacketSize();
|
|
||||||
size_t mac_size = cs->send_encryption_handler->MACSize();
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
this->pos = 0; // We start reading from here
|
|
||||||
this->buffer.shrink_to_fit();
|
this->buffer.shrink_to_fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Packet::PreSendEncryption()
|
||||||
|
{
|
||||||
|
this->encyption_pending = false;
|
||||||
|
size_t offset = EncodedLengthOfPacketSize();
|
||||||
|
size_t mac_size = cs->send_encryption_handler->MACSize();
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is it safe to write to the packet, i.e. didn't we run over the buffer?
|
* Is it safe to write to the packet, i.e. didn't we run over the buffer?
|
||||||
* @param bytes_to_write The amount of bytes we want to try to write.
|
* @param bytes_to_write The amount of bytes we want to try to write.
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user