+/*
+ * 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(const int fd, tos_t tos, int type)
+{
+ // 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;
+#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)
{
-#ifdef IP_TOS
- int x = setsockopt(conn->fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos_t));
+ 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(const int fd, nfmark_t mark)
+{
+#if SO_MARK && USE_LIBCAP
+ const int x = setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(nfmark_t));
if (x < 0)
- debugs(50, 2, "Ip::Qos::setSockTos: setsockopt(IP_TOS) on " << conn << ": " << xstrerror());
+ debugs(50, 2, "setSockNfmark: setsockopt(SO_MARK) on " << fd << ": " << xstrerror());
return x;
+#elif USE_LIBCAP
+ debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(SO_MARK) not supported on this platform");
+ return -1;
#else
- debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(IP_TOS) not supported on this platform");
+ 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)
{
-#if SO_MARK
- int x = setsockopt(conn->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(nfmark_t));
- if (x < 0)
- debugs(50, 2, "setSockNfmark: setsockopt(SO_MARK) on " << conn << ": " << xstrerror());
+ const int x = Ip::Qos::setSockNfmark(conn->fd, mark);
+ if (x >= 0)
+ conn->nfmark = mark;
return x;
-#else
- debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(SO_MARK) not supported on this platform");
- return -1;
-#endif
}
bool
{
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)
{
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)
return false;
}
+