ref:82bccdf69894ee03ac422cc787f1ac9654da359d

Merge commit from fork

SHA: 82bccdf69894ee03ac422cc787f1ac9654da359d
Author: Dave Lane <42013603+ReenigneArcher@users.noreply.github.com>
Date: 2026-09-03 00:08
Parents: ccf97e3
2 files changed +77 -6
Type
src/stream.cpp +30 −5
@@ -4,9 +4,12 @@
*/
// standard includes
#include <cstring>
#include <fstream>
#include <future>
#include <optional>
#include <queue>
#include <utility>
// lib includes
#include <boost/endian/arithmetic.hpp>
@@ -630,6 +633,29 @@
static auto broadcast = safe::make_shared<broadcast_ctx_t>(start_broadcast, end_broadcast);
/**
* @brief Parse a control message from an ENet packet.
*
* @param packet ENet packet containing the control message type and payload.
* @return The message type and payload view, or `std::nullopt` when the packet lacks a complete type.
*/
std::optional<std::pair<std::uint16_t, std::string_view>> parse_control_packet(const ENetPacket &packet) {
if (packet.data == nullptr || packet.dataLength < sizeof(std::uint16_t)) {
return std::nullopt;
}
std::uint16_t type;
std::memcpy(&type, packet.data, sizeof(type));
return std::pair {
type,
std::string_view {
reinterpret_cast<const char *>(packet.data) + sizeof(type),
packet.dataLength - sizeof(type),
},
};
}
session_t *control_server_t::get_session(const net::peer_t peer, uint32_t connect_data) {
{
// Fast path - look up existing session by peer
@@ -740,11 +766,10 @@
case ENET_EVENT_TYPE_RECEIVE:
{
net::packet_t packet {event.packet};
auto message = parse_control_packet(*packet);
auto type = *(std::uint16_t *) packet->data;
std::string_view payload {(char *) packet->data + sizeof(type), packet->dataLength - sizeof(type)};
call(type, session, payload, false);
if (message) {
call(message->first, session, message->second, false);
}
}
break;
case ENET_EVENT_TYPE_CONNECT:
tests/unit/test_stream.cpp +47 −1
@@ -7,14 +7,22 @@
#include "../tests_common.h"
// standard includes
#include <array>
#include <cstdint>
#include <functional>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
// local includes
#include <src/network.h>
namespace stream {
std::vector<uint8_t> concat_and_insert(uint64_t insert_size, uint64_t slice_size, const std::string_view &data1, const std::string_view &data2);
std::optional<std::pair<std::uint16_t, std::string_view>> parse_control_packet(const ENetPacket &packet);
}
} // namespace stream
TEST(ConcatAndInsertTests, ConcatNoInsertionTest) {
char b1[] = {'a', 'b'};
@@ -38,4 +46,42 @@
auto res = stream::concat_and_insert(1, 1, std::string_view {b1, sizeof(b1)}, std::string_view {b2, sizeof(b2)});
auto expected = std::vector<uint8_t> {0, 'a', 0, 'b', 0, 'c', 0, 'd', 0, 'e'};
ASSERT_EQ(res, expected);
}
TEST(ControlPacketTests, RejectsZeroLengthPacket) {
net::packet_t packet {enet_packet_create(nullptr, 0, 0)};
ASSERT_NE(packet, nullptr);
EXPECT_EQ(packet->data, nullptr);
EXPECT_EQ(stream::parse_control_packet(*packet), std::nullopt);
}
TEST(ControlPacketTests, RejectsOneBytePacket) {
const std::uint8_t data {0x06};
net::packet_t packet {enet_packet_create(&data, sizeof(data), 0)};
ASSERT_NE(packet, nullptr);
EXPECT_EQ(stream::parse_control_packet(*packet), std::nullopt);
}
TEST(ControlPacketTests, AcceptsTypeWithoutPayload) {
const std::array<std::uint8_t, 2> data {0x06, 0x02};
net::packet_t packet {enet_packet_create(data.data(), data.size(), 0)};
ASSERT_NE(packet, nullptr);
auto message = stream::parse_control_packet(*packet);
ASSERT_TRUE(message);
EXPECT_EQ(message->first, 0x0206);
EXPECT_TRUE(message->second.empty());
}
TEST(ControlPacketTests, AcceptsTypeAndPayload) {
const std::array<std::uint8_t, 5> data {0x06, 0x02, 'a', 'b', 'c'};
net::packet_t packet {enet_packet_create(data.data(), data.size(), 0)};
ASSERT_NE(packet, nullptr);
auto message = stream::parse_control_packet(*packet);
ASSERT_TRUE(message);
EXPECT_EQ(message->first, 0x0206);
EXPECT_EQ(message->second, "abc");
}