]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/ip/Qos.cci
SourceFormat Enforcement
[thirdparty/squid.git] / src / ip / Qos.cci
index f2a53bc63293919ae37b9fcf546071e6a4a12b9f..f2e2ab923c264e1e5371c82b4ebe3e0d18a692f6 100644 (file)
@@ -1,33 +1,85 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
 /* Inline QOS functions */
+#include "comm/Connection.h"
+#include "Debug.h"
 
 int
-Ip::Qos::setSockTos(int fd, tos_t tos)
+Ip::Qos::setSockTos(const int fd, tos_t tos, int type)
 {
-#ifdef IP_TOS
-    int x = setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos_t));
-    if (x < 0)
-        debugs(50, 2, "Ip::Qos::setSockTos: setsockopt(IP_TOS) on FD " << fd << ": " << xstrerror());
-    return x;
+    // Bug 3731: FreeBSD produces 'invalid option'
+    // unless we pass it a 32-bit variable storing 8-bits of data.
+    // NP: it is documented as 'int' for all systems, even those like Linux which accept 8-bit char
+    //     so we convert to a int before setting.
+    int bTos = tos;
+
+    if (type == AF_INET) {
+#if defined(IP_TOS)
+        const int x = setsockopt(fd, IPPROTO_IP, IP_TOS, &bTos, sizeof(bTos));
+        if (x < 0)
+            debugs(50, 2, "Ip::Qos::setSockTos: setsockopt(IP_TOS) on " << fd << ": " << xstrerror());
+        return x;
 #else
-    debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(IP_TOS) not supported on this platform");
-    return -1;
+        debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(IP_TOS) not supported on this platform");
+        return -1;
+#endif
+    } else { // type == AF_INET6
+#if defined(IPV6_TCLASS)
+        const int x = setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &bTos, sizeof(bTos));
+        if (x < 0)
+            debugs(50, 2, "Ip::Qos::setSockTos: setsockopt(IPV6_TCLASS) on " << fd << ": " << xstrerror());
+        return x;
+#else
+        debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(IPV6_TCLASS) not supported on this platform");
+        return -1;
 #endif
+    }
+
+    /* CANNOT REACH HERE */
+}
+
+int
+Ip::Qos::setSockTos(const Comm::ConnectionPointer &conn, tos_t tos)
+{
+    const int x = Ip::Qos::setSockTos(conn->fd, tos, conn->remote.isIPv4() ? AF_INET : AF_INET6);
+    if (x >= 0)
+        conn->tos = tos;
+
+    return x;
 }
 
 int
-Ip::Qos::setSockNfmark(int fd, nfmark_t mark)
+Ip::Qos::setSockNfmark(const int fd, nfmark_t mark)
 {
-#if SO_MARK
-    int x = setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(nfmark_t));
+#if SO_MARK && USE_LIBCAP
+    const int x = setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(nfmark_t));
     if (x < 0)
-        debugs(50, 2, "setSockNfmark: setsockopt(SO_MARK) on FD " << fd << ": " << xstrerror());
+        debugs(50, 2, "setSockNfmark: setsockopt(SO_MARK) on " << fd << ": " << xstrerror());
     return x;
-#else
+#elif USE_LIBCAP
     debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(SO_MARK) not supported on this platform");
     return -1;
+#else
+    debugs(50, DBG_IMPORTANT, "WARNING: Netfilter marking disabled (netfilter marking requires build with LIBCAP)");
+    return -1;
 #endif
 }
 
+int
+Ip::Qos::setSockNfmark(const Comm::ConnectionPointer &conn, nfmark_t mark)
+{
+    const int x = Ip::Qos::setSockNfmark(conn->fd, mark);
+    if (x >= 0)
+        conn->nfmark = mark;
+    return x;
+}
+
 bool
 Ip::Qos::Config::isHitTosActive() const
 {
@@ -44,12 +96,12 @@ bool
 Ip::Qos::Config::isAclNfmarkActive() const
 {
     acl_nfmark * nfmarkAcls [] = { nfmarkToServer, nfmarkToClient };
-    for (int i=0; i<2; i++) {
+
+    for (int i=0; i<2; ++i) {
         while (nfmarkAcls[i]) {
             acl_nfmark *l = nfmarkAcls[i];
             if (l->nfmark > 0)
-                return true; 
+                return true;
             nfmarkAcls[i] = l->next;
         }
     }
@@ -62,7 +114,7 @@ Ip::Qos::Config::isAclTosActive() const
 {
     acl_tos * tosAcls [] = { tosToServer, tosToClient };
 
-    for (int i=0; i<2; i++) {
+    for (int i=0; i<2; ++i) {
         while (tosAcls[i]) {
             acl_tos *l = tosAcls[i];
             if (l->tos > 0)
@@ -73,3 +125,4 @@ Ip::Qos::Config::isAclTosActive() const
 
     return false;
 }
+