]> granicus.if.org Git - transmission/commitdiff
Improve ToS on IPv6 connections
authorclyang <clyang@clyang.net>
Wed, 2 Aug 2017 10:01:39 +0000 (18:01 +0800)
committerMike Gelfand <mikedld@mikedld.com>
Thu, 3 Aug 2017 03:30:54 +0000 (06:30 +0300)
libtransmission/net.c
libtransmission/net.h
libtransmission/peer-io.c

index 588dc2b27486dc2891bc2efcdf4e56bfc95a11ac..d96476808c894e7581dec0476bfdf2e947f5d98a 100644 (file)
@@ -153,22 +153,70 @@ int tr_address_compare(tr_address const* a, tr_address const* b)
  * TCP sockets
  **********************************************************************/
 
-void tr_netSetTOS(tr_socket_t s, int tos)
+void tr_netSetTOS(tr_socket_t s, int tos, tr_address_type type)
 {
+    if (type == TR_AF_INET)
+    {
 #if defined(IP_TOS) && !defined(_WIN32)
 
-    if (setsockopt(s, IPPROTO_IP, IP_TOS, (void const*)&tos, sizeof(tos)) == -1)
-    {
-        char err_buf[512];
-        tr_logAddNamedInfo("Net", "Can't set TOS '%d': %s", tos, tr_net_strerror(err_buf, sizeof(err_buf), sockerrno));
+        if (setsockopt(s, IPPROTO_IP, IP_TOS, (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 TOS '%d': %s", tos, err_buf);
+        }
+
+#else
+
+        (void)s;
+        (void)tos;
+
+#endif
     }
+    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)
+        {
+            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);
+        }
 
 #else
 
-    (void)s;
-    (void)tos;
+        (void)s;
+        (void)tos;
 
 #endif
+    }
+    else
+    {
+        /* program should never reach here! */
+        tr_logAddNamedInfo("Net", "Something goes wrong while setting TOS/Traffic-Class");
+    }
 }
 
 void tr_netSetCongestionControl(tr_socket_t s, char const* algorithm)
index 8973dc57a09dea6069b003a11b8a9655fa4158a2..82577a04eef7ecf7dff4a7b6c317852a5af4161f 100644 (file)
@@ -128,7 +128,7 @@ tr_socket_t tr_netBindTCP(tr_address const* addr, tr_port port, bool suppressMsg
 
 tr_socket_t tr_netAccept(tr_session* session, tr_socket_t bound, tr_address* setme_addr, tr_port* setme_port);
 
-void tr_netSetTOS(tr_socket_t s, int tos);
+void tr_netSetTOS(tr_socket_t s, int tos, tr_address_type type);
 
 void tr_netSetCongestionControl(tr_socket_t s, char const* algorithm);
 
index 9fd955063d065a0d8542ebd98b65bcc0e47c3fa6..b84ed02de5aa98907ede92c7650c9a4b8297dc69 100644 (file)
@@ -637,7 +637,7 @@ static tr_peerIo* tr_peerIoNew(tr_session* session, tr_bandwidth* parent, tr_add
 
     if (socket.type == TR_PEER_SOCKET_TYPE_TCP)
     {
-        tr_netSetTOS(socket.handle.tcp, session->peerSocketTOS);
+        tr_netSetTOS(socket.handle.tcp, session->peerSocketTOS, addr->type);
         maybeSetCongestionAlgorithm(socket.handle.tcp, session->peer_congestion_algorithm);
     }
 
@@ -993,7 +993,7 @@ int tr_peerIoReconnect(tr_peerIo* io)
     io->event_write = event_new(session->event_base, io->socket.handle.tcp, EV_WRITE, event_write_cb, io);
 
     event_enable(io, pendingEvents);
-    tr_netSetTOS(io->socket.handle.tcp, session->peerSocketTOS);
+    tr_netSetTOS(io->socket.handle.tcp, session->peerSocketTOS, io->addr.type);
     maybeSetCongestionAlgorithm(io->socket.handle.tcp, session->peer_congestion_algorithm);
 
     return 0;