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 #ifndef SQUID_QOSCONFIG_H
10 #define SQUID_QOSCONFIG_H
11 
12 #include "acl/forward.h"
13 #include "hier_code.h"
14 #include "ip/forward.h"
15 
16 #if HAVE_LIBNETFILTER_CONNTRACK_LIBNETFILTER_CONNTRACK_H
17 #include <libnetfilter_conntrack/libnetfilter_conntrack.h>
18 #endif
19 #if HAVE_LIBNETFILTER_CONNTRACK_LIBNETFILTER_CONNTRACK_TCP_H
20 #include <libnetfilter_conntrack/libnetfilter_conntrack_tcp.h>
21 #endif
22 #include <limits>
23 
24 class fde;
25 
26 // TODO: move to new ACL framework
27 class acl_tos
28 {
29     CBDATA_CLASS(acl_tos);
30 
31 public:
acl_tos()32     acl_tos() : next(NULL), aclList(NULL), tos(0) {}
33     ~acl_tos();
34 
35     acl_tos *next;
36     ACLList *aclList;
37     tos_t tos;
38 };
39 
40 // TODO: move to new ACL framework
41 class acl_nfmark
42 {
43     CBDATA_CLASS(acl_nfmark);
44 
45 public:
acl_nfmark()46     acl_nfmark() : next(NULL), aclList(NULL), nfmark(0) {}
47     ~acl_nfmark();
48 
49     acl_nfmark *next;
50     ACLList *aclList;
51     nfmark_t nfmark;
52 };
53 
54 namespace Ip
55 {
56 
57 /**
58  * QOS namespace contains all the QOS functionality: global functions within
59  * the namespace and the configuration parameters within a config class.
60  */
61 namespace Qos
62 {
63 
64 /// Possible Squid roles in connection handling
65 enum ConnectionDirection {
66     dirAccepted, ///< accepted (from a client by Squid)
67     dirOpened ///< opened (by Squid to an origin server or peer)
68 };
69 
70 /**
71 * Function to retrieve the TOS value of the inbound packet.
72 * Called by FwdState::dispatch if QOS options are enabled.
73 * Bug 2537: This part of ZPH only applies to patched Linux kernels
74 * @param server    Server side descriptor of connection to get TOS for
75 * @param clientFde Pointer to client side fde instance to set tosFromServer in
76 */
77 void getTosFromServer(const Comm::ConnectionPointer &server, fde *clientFde);
78 
79 /**
80 * Function to retrieve the netfilter mark value of the connection.
81 * Called by FwdState::dispatch if QOS options are enabled or by
82 * Comm::TcpAcceptor::acceptOne
83 *
84 * @param conn    Pointer to connection to get mark for
85 * @param connDir Specifies connection type (incoming or outgoing)
86 */
87 nfmark_t getNfmarkFromConnection(const Comm::ConnectionPointer &conn, const ConnectionDirection connDir);
88 
89 #if USE_LIBNETFILTERCONNTRACK
90 /**
91 * Callback function to mark connection once it's been found.
92 * This function is called by the libnetfilter_conntrack
93 * libraries, during nfct_query in Ip::Qos::getNfmarkFromServer.
94 * nfct_callback_register is used to register this function.
95 * @param nf_conntrack_msg_type Type of conntrack message
96 * @param nf_conntrack Pointer to the conntrack structure
97 * @param mark Pointer to nfmark_t mark
98 */
99 int getNfmarkCallback(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *mark);
100 #endif
101 
102 /**
103 * Function to work out and then apply to the socket the appropriate
104 * TOS value to set on packets when items have not been retrieved from
105 * local cache. Called by clientReplyContext::sendMoreData if QOS is
106 * enabled for TOS.
107 * @param conn     Descriptor of socket to set the TOS for
108 * @param hierCode Hier code of request
109 */
110 int doTosLocalMiss(const Comm::ConnectionPointer &conn, const hier_code hierCode);
111 
112 /**
113 * Function to work out and then apply to the socket the appropriate
114 * netfilter mark value to set on packets when items have not been
115 * retrieved from local cache. Called by clientReplyContext::sendMoreData
116 * if QOS is enabled for TOS.
117 * @param conn     Descriptor of socket to set the mark for
118 * @param hierCode Hier code of request
119 */
120 int doNfmarkLocalMiss(const Comm::ConnectionPointer &conn, const hier_code hierCode);
121 
122 /**
123 * Function to work out and then apply to the socket the appropriate
124 * TOS value to set on packets when items *have* been retrieved from
125 * local cache. Called by clientReplyContext::doGetMoreData if QOS is
126 * enabled for TOS.
127 * @param conn Descriptor of socket to set the TOS for
128 */
129 int doTosLocalHit(const Comm::ConnectionPointer &conn);
130 
131 /**
132 * Function to work out and then apply to the socket the appropriate
133 * netfilter mark value to set on packets when items *have* been
134 * retrieved from local cache. Called by clientReplyContext::doGetMoreData
135 * if QOS is enabled for TOS.
136 * @param conn Descriptor of socket to set the mark for
137 */
138 int doNfmarkLocalHit(const Comm::ConnectionPointer &conn);
139 
140 /**
141 * Function to set the TOS value of packets. Sets the value on the socket
142 * which then gets copied to the packets.
143 * @param conn Descriptor of socket to set the TOS for
144 */
145 _SQUID_INLINE_ int setSockTos(const Comm::ConnectionPointer &conn, tos_t tos);
146 
147 /**
148 * The low level variant of setSockTos function to set TOS value of packets.
149 * Avoid if you can use the Connection-based setSockTos().
150 * @param fd Descriptor of socket to set the TOS for
151 * @param type The socket family, AF_INET or AF_INET6
152 */
153 _SQUID_INLINE_ int setSockTos(const int fd, tos_t tos, int type);
154 
155 /**
156 * Function to set the netfilter mark value of packets. Sets the value on the
157 * socket which then gets copied to the packets. Called from Ip::Qos::doNfmarkLocalMiss
158 * @param conn Descriptor of socket to set the mark for
159 */
160 _SQUID_INLINE_ int setSockNfmark(const Comm::ConnectionPointer &conn, nfmark_t mark);
161 
162 /**
163 * The low level variant of setSockNfmark function to set the netfilter mark
164 * value of packets.
165 * Avoid if you can use the Connection-based setSockNfmark().
166 * @param fd Descriptor of socket to set the mark for
167 */
168 _SQUID_INLINE_ int setSockNfmark(const int fd, nfmark_t mark);
169 
170 /**
171  * QOS configuration class. Contains all the parameters for QOS functions as well
172  * as functions to check whether either TOS or MARK QOS is enabled.
173  */
174 class Config
175 {
176 public:
177 
178     Config();
~Config()179     ~Config() {}
180 
181     void parseConfigLine();
182 
183     /**
184      * Dump all the configuration values
185      *
186      * NOTE: Due to the low-level nature of the library these
187      * objects are part of the dump function must be self-contained.
188      * which means no StoreEntry references. Just a basic char* buffer.
189      */
190     void dumpConfigLine(char *entry, const char *name) const;
191 
192     /// Whether we should modify TOS flags based on cache hits and misses.
193     _SQUID_INLINE_ bool isHitTosActive() const;
194 
195     /// Whether we should modify netfilter marks based on cache hits and misses.
196     _SQUID_INLINE_ bool isHitNfmarkActive() const;
197 
198     /**
199     * Iterates through any outgoing_nfmark or clientside_nfmark configuration parameters
200     * to find out if any Netfilter marking is required.
201     * This function is used on initialisation to define capabilities required (Netfilter
202     * marking requires CAP_NET_ADMIN).
203     */
204     _SQUID_INLINE_ bool isAclNfmarkActive() const;
205 
206     /**
207     * Iterates through any outgoing_tos or clientside_tos configuration parameters
208     * to find out if packets should be marked with TOS flags.
209     */
210     _SQUID_INLINE_ bool isAclTosActive() const;
211 
212     tos_t tosLocalHit;                  ///< TOS value to apply to local cache hits
213     tos_t tosSiblingHit;                ///< TOS value to apply to hits from siblings
214     tos_t tosParentHit;                 ///< TOS value to apply to hits from parent
215     tos_t tosMiss;                      ///< TOS value to apply to cache misses
216     tos_t tosMissMask;                  ///< Mask for TOS value to apply to cache misses. Applied to the tosMiss value.
217     bool preserveMissTos;               ///< Whether to preserve the TOS value of the inbound packet for misses
218     tos_t preserveMissTosMask;          ///< The mask to apply when preserving the TOS of misses. Applies to preserved value from upstream.
219 
220     nfmark_t markLocalHit;              ///< Netfilter mark value to apply to local cache hits
221     nfmark_t markSiblingHit;            ///< Netfilter mark value to apply to hits from siblings
222     nfmark_t markParentHit;             ///< Netfilter mark value to apply to hits from parent
223     nfmark_t markMiss;                  ///< Netfilter mark value to apply to cache misses
224     nfmark_t markMissMask;              ///< Mask for netfilter mark value to apply to cache misses. Applied to the markMiss value.
225     bool preserveMissMark;              ///< Whether to preserve netfilter mark value of inbound connection
226     nfmark_t preserveMissMarkMask;      ///< The mask to apply when preserving the netfilter mark of misses. Applied to preserved value from upstream.
227 
228     acl_tos *tosToServer;               ///< The TOS that packets to the web server should be marked with, based on ACL
229     acl_tos *tosToClient;               ///< The TOS that packets to the client should be marked with, based on ACL
230     acl_nfmark *nfmarkToServer;         ///< The MARK that packets to the web server should be marked with, based on ACL
231     acl_nfmark *nfmarkToClient;         ///< The MARK that packets to the client should be marked with, based on ACL
232 
233 };
234 
235 /// Globally available instance of Qos::Config
236 extern Config TheConfig;
237 
238 /* legacy parser access wrappers */
239 #define parse_QosConfig(X)  (X)->parseConfigLine()
240 #define free_QosConfig(X)
241 #define dump_QosConfig(e,n,X) do { \
242         char temp[256]; /* random number. change as needed. max config line length. */ \
243         (X).dumpConfigLine(temp,n); \
244             storeAppendPrintf(e, "%s", temp); \
245     } while(0);
246 
247 } // namespace Qos
248 
249 } // namespace Ip
250 
251 #if _USE_INLINE_
252 #include "Qos.cci"
253 #endif
254 
255 #endif /* SQUID_QOSCONFIG_H */
256 
257