refactor: move tr_diffserv_t::Names into serializer (#8088)

* refactor: move tr_diffserv_t::Names into serializer

* Update libtransmission/serializer.cc
This commit is contained in:
Charles Kerr
2026-01-09 14:39:54 -06:00
committed by GitHub
parent cf3799fb42
commit 47832db7b2
4 changed files with 70 additions and 88 deletions

View File

@@ -111,39 +111,6 @@ int tr_make_listen_socket_ipv6only(tr_socket_t const sock)
// - TCP Sockets
[[nodiscard]] std::optional<tr_diffserv_t> tr_diffserv_t::from_string(std::string_view name)
{
auto const needle = tr_strlower(tr_strv_strip(name));
for (auto const& [value, key] : Names)
{
if (needle == key)
{
return tr_diffserv_t(value);
}
}
if (auto value = tr_num_parse<int>(needle); value)
{
return tr_diffserv_t(*value);
}
return {};
}
std::string tr_diffserv_t::toString() const
{
for (auto const& [value, key] : Names)
{
if (value_ == value)
{
return std::string{ key };
}
}
return std::to_string(value_);
}
void tr_netSetDiffServ([[maybe_unused]] tr_socket_t s, [[maybe_unused]] int tos, tr_address_type type)
{
if (s == TR_BAD_SOCKET)

View File

@@ -636,9 +636,7 @@ void tr_net_close_socket(tr_socket_t fd);
// --- TOS / DSCP
/**
* A `toString()` / `from_string()` convenience wrapper around the DiffServ int value
*/
// A serializer-friendly wrapper around the DiffServ int value
class tr_diffserv_t
{
public:
@@ -655,49 +653,8 @@ public:
return value_;
}
[[nodiscard]] static std::optional<tr_diffserv_t> from_string(std::string_view name);
[[nodiscard]] std::string toString() const;
private:
int value_ = 0x04;
// RFCs 2474, 3246, 4594 & 8622
// Service class names are defined in RFC 4594, RFC 5865, and RFC 8622.
// Not all platforms have these IPTOS_ definitions, so hardcode them here
static auto constexpr Names = std::array<std::pair<int, std::string_view>, 28>{ {
{ 0x00, "cs0" }, // IPTOS_CLASS_CS0
{ 0x04, "le" },
{ 0x20, "cs1" }, // IPTOS_CLASS_CS1
{ 0x28, "af11" }, // IPTOS_DSCP_AF11
{ 0x30, "af12" }, // IPTOS_DSCP_AF12
{ 0x38, "af13" }, // IPTOS_DSCP_AF13
{ 0x40, "cs2" }, // IPTOS_CLASS_CS2
{ 0x48, "af21" }, // IPTOS_DSCP_AF21
{ 0x50, "af22" }, // IPTOS_DSCP_AF22
{ 0x58, "af23" }, // IPTOS_DSCP_AF23
{ 0x60, "cs3" }, // IPTOS_CLASS_CS3
{ 0x68, "af31" }, // IPTOS_DSCP_AF31
{ 0x70, "af32" }, // IPTOS_DSCP_AF32
{ 0x78, "af33" }, // IPTOS_DSCP_AF33
{ 0x80, "cs4" }, // IPTOS_CLASS_CS4
{ 0x88, "af41" }, // IPTOS_DSCP_AF41
{ 0x90, "af42" }, // IPTOS_DSCP_AF42
{ 0x98, "af43" }, // IPTOS_DSCP_AF43
{ 0xa0, "cs5" }, // IPTOS_CLASS_CS5
{ 0xb8, "ef" }, // IPTOS_DSCP_EF
{ 0xc0, "cs6" }, // IPTOS_CLASS_CS6
{ 0xe0, "cs7" }, // IPTOS_CLASS_CS7
// <netinet/ip.h> lists these TOS names as deprecated,
// but keep them defined here for backward compatibility
{ 0x00, "routine" }, // IPTOS_PREC_ROUTINE
{ 0x02, "lowcost" }, // IPTOS_LOWCOST
{ 0x02, "mincost" }, // IPTOS_MINCOST
{ 0x04, "reliable" }, // IPTOS_RELIABILITY
{ 0x08, "throughput" }, // IPTOS_THROUGHPUT
{ 0x10, "lowdelay" }, // IPTOS_LOWDELAY
} };
};
// set the IPTOS_ value for the specified socket

View File

@@ -461,23 +461,71 @@ tr_variant from_string(std::string const& val)
// ---
// RFCs 2474, 3246, 4594 & 8622
// Service class names are defined in RFC 4594, RFC 5865, and RFC 8622.
// Not all platforms have these IPTOS_ definitions, so hardcode them here
auto constexpr DiffServKeys = Lookup<int, 28U>{ {
{ "cs0", 0x00 }, // IPTOS_CLASS_CS0
{ "le", 0x04 },
{ "cs1", 0x20 }, // IPTOS_CLASS_CS1
{ "af11", 0x28 }, // IPTOS_DSCP_AF11
{ "af12", 0x30 }, // IPTOS_DSCP_AF12
{ "af13", 0x38 }, // IPTOS_DSCP_AF13
{ "cs2", 0x40 }, // IPTOS_CLASS_CS2
{ "af21", 0x48 }, // IPTOS_DSCP_AF21
{ "af22", 0x50 }, // IPTOS_DSCP_AF22
{ "af23", 0x58 }, // IPTOS_DSCP_AF23
{ "cs3", 0x60 }, // IPTOS_CLASS_CS3
{ "af31", 0x68 }, // IPTOS_DSCP_AF31
{ "af32", 0x70 }, // IPTOS_DSCP_AF32
{ "af33", 0x78 }, // IPTOS_DSCP_AF33
{ "cs4", 0x80 }, // IPTOS_CLASS_CS4
{ "af41", 0x88 }, // IPTOS_DSCP_AF41
{ "af42", 0x90 }, // IPTOS_DSCP_AF42
{ "af43", 0x98 }, // IPTOS_DSCP_AF43
{ "cs5", 0xa0 }, // IPTOS_CLASS_CS5
{ "ef", 0xb8 }, // IPTOS_DSCP_EF
{ "cs6", 0xc0 }, // IPTOS_CLASS_CS6
{ "cs7", 0xe0 }, // IPTOS_CLASS_CS7
// <netinet/ip.h> lists these TOS names as deprecated,
// but keep them defined here for backward compatibility
{ "routine", 0x00 }, // IPTOS_PREC_ROUTINE
{ "lowcost", 0x02 }, // IPTOS_LOWCOST
{ "mincost", 0x02 }, // IPTOS_MINCOST
{ "reliable", 0x04 }, // IPTOS_RELIABILITY
{ "throughput", 0x08 }, // IPTOS_THROUGHPUT
{ "lowdelay", 0x10 }, // IPTOS_LOWDELAY
} };
bool to_diffserv_t(tr_variant const& src, tr_diffserv_t* tgt)
{
static constexpr auto& Keys = DiffServKeys;
if (auto const val = src.value_if<std::string_view>())
{
if (auto const tos = tr_diffserv_t::from_string(*val); tos)
{
*tgt = *tos;
return true;
}
auto const needle = tr_strlower(tr_strv_strip(*val));
return false;
for (auto const& [name, value] : Keys)
{
if (name == needle)
{
*tgt = tr_diffserv_t{ value };
return true;
}
}
}
if (auto const val = src.value_if<int64_t>())
{
*tgt = tr_diffserv_t{ static_cast<int>(*val) };
return true;
for (auto const& [name, value] : Keys)
{
if (value == *val)
{
*tgt = tr_diffserv_t{ value };
return true;
}
}
}
return false;
@@ -485,7 +533,17 @@ bool to_diffserv_t(tr_variant const& src, tr_diffserv_t* tgt)
tr_variant from_diffserv_t(tr_diffserv_t const& val)
{
return val.toString();
static constexpr auto& Keys = DiffServKeys;
for (auto const& [key, value] : Keys)
{
if (value == val)
{
return key;
}
}
return static_cast<int64_t>(val);
}
// ---

View File

@@ -390,11 +390,11 @@ TEST_F(SettingsTest, canSaveDiffServ)
auto settings = tr_session::Settings{};
ASSERT_NE(ChangedValue, settings.peer_socket_diffserv);
settings.peer_socket_diffserv = tr_diffserv_t(0x20);
settings.peer_socket_diffserv = ChangedValue;
auto const map = settings.save();
auto const val = map.value_if<std::string_view>(Key);
ASSERT_TRUE(val);
EXPECT_EQ(ChangedValue.toString(), *val);
EXPECT_EQ("cs1"sv, *val);
}
TEST_F(SettingsTest, canLoadVerify)