1/* 2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors 3 * 4 * Squid software is distributed under GPLv2+ license and includes 5 * contributions from numerous individuals and organizations. 6 * Please see the COPYING and CONTRIBUTORS files for details. 7 */ 8 9/* Inline QOS functions */ 10#include "comm/Connection.h" 11#include "Debug.h" 12 13int 14Ip::Qos::setSockTos(const int fd, tos_t tos, int type) 15{ 16 // Bug 3731: FreeBSD produces 'invalid option' 17 // unless we pass it a 32-bit variable storing 8-bits of data. 18 // NP: it is documented as 'int' for all systems, even those like Linux which accept 8-bit char 19 // so we convert to a int before setting. 20 int bTos = tos; 21 22 debugs(50, 3, "for FD " << fd << " to " << bTos); 23 24 if (type == AF_INET) { 25#if defined(IP_TOS) 26 const int x = setsockopt(fd, IPPROTO_IP, IP_TOS, &bTos, sizeof(bTos)); 27 if (x < 0) { 28 int xerrno = errno; 29 debugs(50, 2, "setsockopt(IP_TOS) on " << fd << ": " << xstrerr(xerrno)); 30 } 31 return x; 32#else 33 debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(IP_TOS) not supported on this platform"); 34 return -1; 35#endif 36 } else { // type == AF_INET6 37#if defined(IPV6_TCLASS) 38 const int x = setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &bTos, sizeof(bTos)); 39 if (x < 0) { 40 int xerrno = errno; 41 debugs(50, 2, "setsockopt(IPV6_TCLASS) on " << fd << ": " << xstrerr(xerrno)); 42 } 43 return x; 44#else 45 debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(IPV6_TCLASS) not supported on this platform"); 46 return -1; 47#endif 48 } 49 50 /* CANNOT REACH HERE */ 51} 52 53int 54Ip::Qos::setSockTos(const Comm::ConnectionPointer &conn, tos_t tos) 55{ 56 const int x = Ip::Qos::setSockTos(conn->fd, tos, conn->remote.isIPv4() ? AF_INET : AF_INET6); 57 conn->tos = (x >= 0) ? tos : 0; 58 return x; 59} 60 61int 62Ip::Qos::setSockNfmark(const int fd, nfmark_t mark) 63{ 64#if SO_MARK && USE_LIBCAP 65 debugs(50, 3, "for FD " << fd << " to " << mark); 66 const int x = setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(nfmark_t)); 67 if (x < 0) { 68 int xerrno = errno; 69 debugs(50, 2, "setsockopt(SO_MARK) on " << fd << ": " << xstrerr(xerrno)); 70 } 71 return x; 72#elif USE_LIBCAP 73 debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(SO_MARK) not supported on this platform"); 74 return -1; 75#else 76 debugs(50, DBG_IMPORTANT, "WARNING: Netfilter marking disabled (netfilter marking requires build with LIBCAP)"); 77 return -1; 78#endif 79} 80 81int 82Ip::Qos::setSockNfmark(const Comm::ConnectionPointer &conn, nfmark_t mark) 83{ 84 const int x = Ip::Qos::setSockNfmark(conn->fd, mark); 85 conn->nfmark = (x >= 0) ? mark : 0; 86 return x; 87} 88 89bool 90Ip::Qos::Config::isHitTosActive() const 91{ 92 return (tosLocalHit || tosSiblingHit || tosParentHit || tosMiss || preserveMissTos); 93} 94 95bool 96Ip::Qos::Config::isHitNfmarkActive() const 97{ 98 return (markLocalHit || markSiblingHit || markParentHit || markMiss || preserveMissMark); 99} 100 101bool 102Ip::Qos::Config::isAclNfmarkActive() const 103{ 104 acl_nfmark * nfmarkAcls [] = { nfmarkToServer, nfmarkToClient }; 105 106 for (int i=0; i<2; ++i) { 107 while (nfmarkAcls[i]) { 108 acl_nfmark *l = nfmarkAcls[i]; 109 if (l->nfmark > 0) 110 return true; 111 nfmarkAcls[i] = l->next; 112 } 113 } 114 115 return false; 116} 117 118bool 119Ip::Qos::Config::isAclTosActive() const 120{ 121 acl_tos * tosAcls [] = { tosToServer, tosToClient }; 122 123 for (int i=0; i<2; ++i) { 124 while (tosAcls[i]) { 125 acl_tos *l = tosAcls[i]; 126 if (l->tos > 0) 127 return true; 128 tosAcls[i] = l->next; 129 } 130 } 131 132 return false; 133} 134 135