From bcf8128400a1055d920757c0e5924a34a371824a Mon Sep 17 00:00:00 2001 From: Mingye Wang Date: Sun, 21 Jul 2019 19:09:04 +0800 Subject: [PATCH] Unify/Modernize TOS to DSCP standards (#737) * Unify/Modernize TOS to DSCP standards The set of pre-named TOS values are now renamed to the latest DSCP standards, with traffic classes and everything exciting. To keep everything in the same place, a segment has been added to net.h to keep the currently named values. A result of these changes is that "lowcost" is probably no longer harmless, as it now encourages the router to preferentially drop the packages when bandwidth requires so. "lowdelay" is assigned to a pretty high AF class for SIP and stuff. I am not sure at all about the "throughput" assignment. I mean, the whole point of DSCP-fication is translating from the old ToS bits to a more precedence-based notation, and precedence is supposed to lie beside the old 4 ToS bits... A funny interaction between the AFxy and the old ToS fields lies in the old "reliability" (0x08) field. All odd numbers of y (1, 3 : low, high) switches it on. If you spend 5 more minutes on it you can probably come up with "pun" values that hold similar meanings in DSCP and Prec/ToS. By removing the IPv6 override, I should have kind of satisfied the #692 request. Fixes: #692 --- libtransmission/net.c | 26 ++------------------------ libtransmission/net.h | 9 +++++++++ libtransmission/session.c | 18 +++++++++--------- 3 files changed, 20 insertions(+), 33 deletions(-) diff --git a/libtransmission/net.c b/libtransmission/net.c index fd5f37e65..ecc99aded 100644 --- a/libtransmission/net.c +++ b/libtransmission/net.c @@ -176,33 +176,11 @@ void tr_netSetTOS(tr_socket_t s, int tos, tr_address_type type) else if (type == TR_AF_INET6) { #if defined(IPV6_TCLASS) && !defined(_WIN32) - - int dscp = 0; - - switch (tos) - { - case 0x10: - dscp = 0x20; /* lowcost (CS1) */ - break; - - case 0x08: - dscp = 0x28; /* throughput (AF11) */ - break; - - case 0x04: - dscp = 0x04; /* reliability */ - break; - - case 0x02: - dscp = 0x30; /* low delay (AF12) */ - break; - } - - if (setsockopt(s, IPPROTO_IPV6, IPV6_TCLASS, (void const*)&dscp, sizeof(dscp)) == -1) + if (setsockopt(s, IPPROTO_IPV6, IPV6_TCLASS, (void const*)&tos, sizeof(tos)) == -1) { char err_buf[512]; tr_net_strerror(err_buf, sizeof(err_buf), sockerrno); - tr_logAddNamedInfo("Net", "Can't set IPv6 QoS '%d': %s", dscp, err_buf); + tr_logAddNamedInfo("Net", "Can't set IPv6 QoS '%d': %s", tos, err_buf); } #else diff --git a/libtransmission/net.h b/libtransmission/net.h index 66b3449e7..1e4361061 100644 --- a/libtransmission/net.h +++ b/libtransmission/net.h @@ -118,6 +118,15 @@ static inline bool tr_address_is_valid(tr_address const* a) * Sockets **********************************************************************/ +/* https://en.wikipedia.org/wiki/Differentiated_services#Class_Selector */ +enum +{ + TR_IPTOS_LOWCOST = 0x38, /* AF13: low prio, high drop */ + TR_IPTOS_LOWDELAY = 0x70, /* AF32: high prio, mid drop */ + TR_IPTOS_THRUPUT = 0x20, /* CS1: low prio, undef drop */ + TR_IPTOS_RELIABLE = 0x28 /* AF11: low prio, low drop */ +}; + struct tr_session; struct tr_peer_socket tr_netOpenPeerSocket(tr_session* session, tr_address const* addr, tr_port port, bool clientIsSeed); diff --git a/libtransmission/session.c b/libtransmission/session.c index 73e1f2569..94faf446d 100644 --- a/libtransmission/session.c +++ b/libtransmission/session.c @@ -265,27 +265,27 @@ static int parse_tos(char const* str) if (evutil_ascii_strcasecmp(str, "lowcost") == 0) { - return 0x10; + return TR_IPTOS_LOWCOST; } if (evutil_ascii_strcasecmp(str, "mincost") == 0) { - return 0x10; + return TR_IPTOS_LOWCOST; } if (evutil_ascii_strcasecmp(str, "throughput") == 0) { - return 0x08; + return TR_IPTOS_THRUPUT; } if (evutil_ascii_strcasecmp(str, "reliability") == 0) { - return 0x04; + return TR_IPTOS_RELIABLE; } if (evutil_ascii_strcasecmp(str, "lowdelay") == 0) { - return 0x02; + return TR_IPTOS_LOWDELAY; } value = strtol(str, &p, 0); @@ -307,16 +307,16 @@ static char const* format_tos(int value) case 0: return "default"; - case 0x10: + case TR_IPTOS_LOWCOST: return "lowcost"; - case 0x08: + case TR_IPTOS_THRUPUT: return "throughput"; - case 0x04: + case TR_IPTOS_RELIABLE: return "reliability"; - case 0x02: + case TR_IPTOS_LOWDELAY: return "lowdelay"; default: