Squid Web Cache master
Loading...
Searching...
No Matches
QosConfig.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2025 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#include "squid.h"
10#include "acl/Gadgets.h"
11#include "base/IoManip.h"
12#include "base/PackableStream.h"
13#include "base/TextException.h"
14#include "cache_cf.h"
15#include "comm/Connection.h"
16#include "compat/cmsg.h"
17#include "compat/socket.h"
18#include "ConfigParser.h"
19#include "fde.h"
20#include "globals.h"
21#include "hier_code.h"
22#include "ip/QosConfig.h"
23#include "ip/tools.h"
24#include "Parsing.h"
25#include "sbuf/Stream.h"
26#include "Store.h"
27
28#include <cerrno>
29#include <limits>
30
32
38
40
46
47void
49{
50#if USE_QOS_TOS && _SQUID_LINUX_
51 /* Bug 2537: This part of ZPH only applies to patched Linux kernels. */
52 tos_t tos = 1;
53 int tos_len = sizeof(tos);
54 clientFde->tosFromServer = 0;
55 if (xsetsockopt(server->fd,SOL_IP,IP_RECVTOS,&tos,tos_len)==0) {
56 unsigned char buf[512];
57 int len = 512;
58 if (xgetsockopt(server->fd,SOL_IP,IP_PKTOPTIONS,buf,(socklen_t*)&len) == 0) {
59 /* Parse the PKTOPTIONS structure to locate the TOS data message
60 * prepared in the kernel by the ZPH incoming TCP TOS preserving
61 * patch.
62 */
63 unsigned char * pbuf = buf;
64 while (pbuf-buf < len) {
65 struct cmsghdr *o = (struct cmsghdr*)pbuf;
66 if (o->cmsg_len<=0)
67 break;
68
69 if (o->cmsg_level == SOL_IP && o->cmsg_type == IP_TOS) {
70 int *tmp = (int*)SQUID_CMSG_DATA(o);
71 clientFde->tosFromServer = (tos_t)*tmp;
72 break;
73 }
74 pbuf += CMSG_LEN(o->cmsg_len);
75 }
76 } else {
77 int xerrno = errno;
78 debugs(33, DBG_IMPORTANT, "ERROR: QOS: getsockopt(IP_PKTOPTIONS) failure on " << server << " " << xstrerr(xerrno));
79 }
80 } else {
81 int xerrno = errno;
82 debugs(33, DBG_IMPORTANT, "ERROR: QOS: setsockopt(IP_RECVTOS) failure on " << server << " " << xstrerr(xerrno));
83 }
84#else
85 (void)server;
86 (void)clientFde;
87#endif
88}
89
90#if USE_LIBNETFILTERCONNTRACK
100static int
101getNfmarkCallback(enum nf_conntrack_msg_type, struct nf_conntrack *ct, void *connmark)
102{
103 auto *mark = static_cast<nfmark_t *>(connmark);
104 *mark = nfct_get_attr_u32(ct, ATTR_MARK);
105 debugs(17, 3, "mark=0x" << asHex(*mark));
106 return NFCT_CB_CONTINUE;
107}
108
113static nf_conntrack *
114prepareConntrackQuery(const Ip::Address &src, const Ip::Address &dst)
115{
116 /* Allocate a new conntrack */
117 if (auto ct = nfct_new()) {
118 // Prepare data needed to find the connection in the conntrack table.
119 // We need the local and remote IP address, and the local and remote
120 // port numbers.
121 if (Ip::EnableIpv6 && src.isIPv6()) {
122 nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET6);
123 struct in6_addr conn_fde_dst_ip6;
124 dst.getInAddr(conn_fde_dst_ip6);
125 nfct_set_attr(ct, ATTR_ORIG_IPV6_DST, conn_fde_dst_ip6.s6_addr);
126 struct in6_addr conn_fde_src_ip6;
127 src.getInAddr(conn_fde_src_ip6);
128 nfct_set_attr(ct, ATTR_ORIG_IPV6_SRC, conn_fde_src_ip6.s6_addr);
129 } else {
130 nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET);
131 struct in_addr conn_fde_dst_ip;
132 dst.getInAddr(conn_fde_dst_ip);
133 nfct_set_attr_u32(ct, ATTR_ORIG_IPV4_DST, conn_fde_dst_ip.s_addr);
134 struct in_addr conn_fde_src_ip;
135 src.getInAddr(conn_fde_src_ip);
136 nfct_set_attr_u32(ct, ATTR_ORIG_IPV4_SRC, conn_fde_src_ip.s_addr);
137 }
138
139 nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_TCP);
140 nfct_set_attr_u16(ct, ATTR_ORIG_PORT_DST, htons(dst.port()));
141 nfct_set_attr_u16(ct, ATTR_ORIG_PORT_SRC, htons(src.port()));
142
143 return ct;
144 }
145
146 return nullptr;
147}
148#endif
149
152{
153 nfmark_t mark = 0;
154#if USE_LIBNETFILTERCONNTRACK
155 const auto src = (connDir == Ip::Qos::dirAccepted) ? conn->remote : conn->local;
156 const auto dst = (connDir == Ip::Qos::dirAccepted) ? conn->local : conn->remote;
157
158 if (const auto ct = prepareConntrackQuery(src, dst)) {
159 // Open a handle to the conntrack
160 if (struct nfct_handle *h = nfct_open(CONNTRACK, 0)) {
161 // Register the callback. The callback function will record the mark value.
162 nfct_callback_register(h, NFCT_T_ALL, getNfmarkCallback, static_cast<void *>(&mark));
163 // Query the conntrack table using the data previously set
164 int x = nfct_query(h, NFCT_Q_GET, ct);
165 if (x == -1) {
166 const int xerrno = errno;
167 debugs(17, 2, "QOS: Failed to retrieve connection mark: (" << x << ") " << xstrerr(xerrno)
168 << " (Destination " << dst << ", source " << src << ")" );
169 }
170 nfct_close(h);
171 } else {
172 debugs(17, 2, "QOS: Failed to open conntrack handle for netfilter CONNMARK retrieval.");
173 }
174 nfct_destroy(ct);
175 } else {
176 debugs(17, 2, "QOS: Failed to allocate new conntrack for netfilter CONNMARK retrieval.");
177 }
178#else
179 (void)conn;
180 (void)connDir;
181#endif
182 return mark;
183}
184
185bool
187{
188 bool ret = false;
189
190#if USE_LIBNETFILTERCONNTRACK
191 const auto src = (connDir == Ip::Qos::dirAccepted) ? conn->remote : conn->local;
192 const auto dst = (connDir == Ip::Qos::dirAccepted) ? conn->local : conn->remote;
193
194 const nfmark_t newMark = cm.applyToMark(conn->nfConnmark);
195
196 // No need to do anything if a CONNMARK has not changed.
197 if (newMark == conn->nfConnmark)
198 return true;
199
200 if (const auto ct = prepareConntrackQuery(src, dst)) {
201 // Open a handle to the conntrack
202 if (struct nfct_handle *h = nfct_open(CONNTRACK, 0)) {
203 nfct_set_attr_u32(ct, ATTR_MARK, newMark);
204 // Update the conntrack table using the new mark. We do not need a callback here.
205 const int queryResult = nfct_query(h, NFCT_Q_UPDATE, ct);
206 if (queryResult == 0) {
207 conn->nfConnmark = newMark;
208 ret = true;
209 } else {
210 const int xerrno = errno;
211 debugs(17, 2, "QOS: Failed to modify connection mark: (" << queryResult << ") " << xstrerr(xerrno)
212 << " (Destination " << dst << ", source " << src << ")" );
213 }
214 nfct_close(h);
215 } else {
216 debugs(17, 2, "QOS: Failed to open conntrack handle for netfilter CONNMARK modification.");
217 }
218 nfct_destroy(ct);
219 } else {
220 debugs(17, 2, "QOS: Failed to allocate new conntrack for netfilter CONNMARK modification.");
221 }
222#else /* USE_LIBNETFILTERCONNTRACK */
223 (void)conn;
224 (void)connDir;
225 (void)cm;
226#endif /* USE_LIBNETFILTERCONNTRACK */
227 return ret;
228}
229
230int
232{
233 tos_t tos = 0;
234 if (Ip::Qos::TheConfig.tosSiblingHit && hierCode==SIBLING_HIT) {
236 debugs(33, 2, "QOS: Sibling Peer hit with hier code=" << hierCode << ", TOS=" << int(tos));
237 } else if (Ip::Qos::TheConfig.tosParentHit && hierCode==PARENT_HIT) {
239 debugs(33, 2, "QOS: Parent Peer hit with hier code=" << hierCode << ", TOS=" << int(tos));
240 } else if (Ip::Qos::TheConfig.preserveMissTos) {
241 tos = fd_table[conn->fd].tosFromServer & Ip::Qos::TheConfig.preserveMissTosMask;
242 tos = (tos & ~Ip::Qos::TheConfig.tosMissMask) | (Ip::Qos::TheConfig.tosMiss & Ip::Qos::TheConfig.tosMissMask);
243 debugs(33, 2, "QOS: Preserving TOS on miss, TOS=" << int(tos));
244 } else if (Ip::Qos::TheConfig.tosMiss) {
246 debugs(33, 2, "QOS: Cache miss, setting TOS=" << int(tos));
247 }
248 return setSockTos(conn, tos);
249}
250
251int
253{
254 nfmark_t mark = 0;
255 if (Ip::Qos::TheConfig.markSiblingHit && hierCode==SIBLING_HIT) {
257 debugs(33, 2, "QOS: Sibling Peer hit with hier code=" << hierCode << ", Mark=" << mark);
258 } else if (Ip::Qos::TheConfig.markParentHit && hierCode==PARENT_HIT) {
260 debugs(33, 2, "QOS: Parent Peer hit with hier code=" << hierCode << ", Mark=" << mark);
261 } else if (Ip::Qos::TheConfig.preserveMissMark) {
262 mark = fd_table[conn->fd].nfConnmarkFromServer & Ip::Qos::TheConfig.preserveMissMarkMask;
263 mark = (mark & ~Ip::Qos::TheConfig.markMissMask) | (Ip::Qos::TheConfig.markMiss & Ip::Qos::TheConfig.markMissMask);
264 debugs(33, 2, "QOS: Preserving mark on miss, Mark=" << mark);
265 } else if (Ip::Qos::TheConfig.markMiss) {
267 debugs(33, 2, "QOS: Cache miss, setting Mark=" << mark);
268 }
269 return setSockNfmark(conn, mark);
270}
271
272int
274{
275 debugs(33, 2, "QOS: Setting TOS for local hit, TOS=" << int(Ip::Qos::TheConfig.tosLocalHit));
276 return setSockTos(conn, Ip::Qos::TheConfig.tosLocalHit);
277}
278
279int
281{
282 debugs(33, 2, "QOS: Setting netfilter mark for local hit, mark=" << Ip::Qos::TheConfig.markLocalHit);
283 return setSockNfmark(conn, Ip::Qos::TheConfig.markLocalHit);
284}
285
286/* Qos::Config class */
287
289
290Ip::Qos::Config::Config() : tosLocalHit(0), tosSiblingHit(0), tosParentHit(0),
291 tosMiss(0), tosMissMask(0), preserveMissTos(false),
292 preserveMissTosMask(0xFF), markLocalHit(0), markSiblingHit(0),
293 markParentHit(0), markMiss(0), markMissMask(0),
294 preserveMissMark(false), preserveMissMarkMask(0xFFFFFFFF),
295 tosToServer(nullptr), tosToClient(nullptr), nfmarkToServer(nullptr),
296 nfmarkToClient(nullptr)
297{
298}
299
300void
302{
303 /* parse options ... */
304 char *token;
305 /* These are set as appropriate and then used to check whether the initial loop has been done */
306 bool mark = false;
307 bool tos = false;
308 /* Assume preserve is true. We don't set at initialisation as this affects isHitTosActive().
309 We have to do this now, as we may never match the 'tos' parameter below */
310#if !USE_QOS_TOS
311 throw TextException(ToSBuf("Invalid option 'qos_flows'. QOS features not enabled in this build"), Here());
312#endif
313
314 while ( (token = ConfigParser::NextToken()) ) {
315
316 // Work out TOS or mark. Default to TOS for backwards compatibility
317 if (!(mark || tos)) {
318 if (strncmp(token, "mark",4) == 0) {
319#if HAVE_LIBCAP && SO_MARK
320 mark = true;
321 // Assume preserve is true. We don't set at initialisation as this affects isHitNfmarkActive()
322#if USE_LIBNETFILTERCONNTRACK
323 preserveMissMark = true;
324# else // USE_LIBNETFILTERCONNTRACK
325 preserveMissMark = false;
326 debugs(3, DBG_IMPORTANT, "WARNING: Squid not compiled with Netfilter conntrack library. "
327 << "Netfilter mark preservation not available.");
328#endif // USE_LIBNETFILTERCONNTRACK
329
330#else // HAVE_LIBCAP && SO_MARK
331 throw TextException(ToSBuf("Invalid parameter 'mark' in qos_flows option. ",
332 "Linux Netfilter marking not available on this platform."), Here());
333#endif
334 } else if (strncmp(token, "tos",3) == 0) {
335 preserveMissTos = true;
336 tos = true;
337 } else {
338 preserveMissTos = true;
339 tos = true;
340 }
341 }
342
343 if (strncmp(token, "local-hit=",10) == 0) {
344
345 if (mark) {
346 if (!xstrtoui(&token[10], nullptr, &markLocalHit, 0, std::numeric_limits<nfmark_t>::max())) {
347 throw TextException(ToSBuf("Bad mark local-hit value ", &token[10]), Here());
348 }
349 } else {
350 unsigned int v = 0;
351 if (!xstrtoui(&token[10], nullptr, &v, 0, std::numeric_limits<tos_t>::max())) {
352 throw TextException(ToSBuf("Bad TOS local-hit value ", &token[10]), Here());
353 }
354 tosLocalHit = (tos_t)v;
355 }
356
357 } else if (strncmp(token, "sibling-hit=",12) == 0) {
358
359 if (mark) {
360 if (!xstrtoui(&token[12], nullptr, &markSiblingHit, 0, std::numeric_limits<nfmark_t>::max())) {
361 throw TextException(ToSBuf("Bad mark sibling-hit value ", &token[12]), Here());
362 }
363 } else {
364 unsigned int v = 0;
365 if (!xstrtoui(&token[12], nullptr, &v, 0, std::numeric_limits<tos_t>::max())) {
366 throw TextException(ToSBuf("Bad TOS sibling-hit value ", &token[12]), Here());
367 }
368 tosSiblingHit = (tos_t)v;
369 }
370
371 } else if (strncmp(token, "parent-hit=",11) == 0) {
372
373 if (mark) {
374 if (!xstrtoui(&token[11], nullptr, &markParentHit, 0, std::numeric_limits<nfmark_t>::max())) {
375 throw TextException(ToSBuf("Bad mark parent-hit value ", &token[11]), Here());
376 }
377 } else {
378 unsigned int v = 0;
379 if (!xstrtoui(&token[11], nullptr, &v, 0, std::numeric_limits<tos_t>::max())) {
380 throw TextException(ToSBuf("Bad TOS parent-hit value ", &token[11]), Here());
381 }
382 tosParentHit = (tos_t)v;
383 }
384
385 } else if (strncmp(token, "miss=",5) == 0) {
386
387 if (mark) {
388 char *end = nullptr;
389 if (!xstrtoui(&token[5], &end, &markMiss, 0, std::numeric_limits<nfmark_t>::max())) {
390 throw TextException(ToSBuf("Bad mark miss value ", &token[5]), Here());
391 }
392 Assure(end);
393 if (*end == '/') {
394 if (!xstrtoui(end + 1, nullptr, &markMissMask, 0, std::numeric_limits<nfmark_t>::max())) {
395 debugs(3, DBG_CRITICAL, "ERROR: Bad mark miss mask value " << (end + 1) << ". Using 0xFFFFFFFF instead.");
396 markMissMask = 0xFFFFFFFF;
397 }
398 } else {
399 markMissMask = 0xFFFFFFFF;
400 }
401 } else {
402 char *end = nullptr;
403 unsigned int v = 0;
404 if (!xstrtoui(&token[5], &end, &v, 0, std::numeric_limits<tos_t>::max())) {
405 throw TextException(ToSBuf("Bad TOS miss value ", &token[5]), Here());
406 }
407 tosMiss = (tos_t)v;
408 Assure(end);
409 if (*end == '/') {
410 if (!xstrtoui(end + 1, nullptr, &v, 0, std::numeric_limits<tos_t>::max())) {
411 debugs(3, DBG_CRITICAL, "ERROR: Bad TOS miss mask value " << (end + 1) << ". Using 0xFF instead.");
412 tosMissMask = 0xFF;
413 } else
414 tosMissMask = (tos_t)v;
415 } else {
416 tosMissMask = 0xFF;
417 }
418 }
419
420 } else if (strcmp(token, "disable-preserve-miss") == 0) {
421
422 if (preserveMissTosMask!=0xFFU || preserveMissMarkMask!=0xFFFFFFFFU) {
423 throw TextException(ToSBuf("miss-mask feature cannot be set with disable-preserve-miss"), Here());
424 }
425 if (mark) {
426 preserveMissMark = false;
427 preserveMissMarkMask = 0;
428 } else {
429 preserveMissTos = false;
430 preserveMissTosMask = 0;
431 }
432
433 } else if (strncmp(token, "miss-mask=",10) == 0) {
434
435 if (mark && preserveMissMark) {
436 if (!xstrtoui(&token[10], nullptr, &preserveMissMarkMask, 0, std::numeric_limits<nfmark_t>::max())) {
437 throw TextException(ToSBuf("Bad mark miss-mark value ", &token[10]), Here());
438 }
439 } else if (preserveMissTos) {
440 unsigned int v = 0;
441 if (!xstrtoui(&token[10], nullptr, &v, 0, std::numeric_limits<tos_t>::max())) {
442 throw TextException(ToSBuf("Bad TOS miss-mark value ", &token[10]), Here());
443 }
444 preserveMissTosMask = (tos_t)v;
445 } else {
446 throw TextException(ToSBuf("miss-mask feature cannot be set without miss-preservation enabled"), Here());
447 }
448
449 }
450 }
451}
452
454template <class Integer>
455static auto asQosConfigHex(const Integer n) { return asHex(n).upperCase().minDigits(2); }
456
458void
459Ip::Qos::Config::dumpConfigLine(std::ostream &os, const char *directiveName) const
460{
461 if (isHitTosActive()) {
462 os << directiveName << " tos";
463
464 if (tosLocalHit > 0) {
465 os << " local-hit=0x" << asQosConfigHex(tosLocalHit);
466 }
467 if (tosSiblingHit > 0) {
468 os << " sibling-hit=0x" << asQosConfigHex(tosSiblingHit);
469 }
470 if (tosParentHit > 0) {
471 os << " parent-hit=0x" << asQosConfigHex(tosParentHit);
472 }
473 if (tosMiss > 0) {
474 os << " miss=0x" << asQosConfigHex(tosMiss);
475 if (tosMissMask!=0xFFU) {
476 os << "/0x" << asQosConfigHex(tosMissMask);
477 }
478 }
479 if (preserveMissTos == 0) {
480 os << " disable-preserve-miss";
481 }
482 if (preserveMissTos && preserveMissTosMask != 0) {
483 os << " miss-mask=0x" << asQosConfigHex(preserveMissTosMask);
484 }
485 os << "\n";
486 return;
487 }
488
489 if (isHitNfmarkActive()) {
490 os << directiveName << " mark";
491
492 if (markLocalHit > 0) {
493 os << " local-hit=0x" << asQosConfigHex(markLocalHit);
494 }
495 if (markSiblingHit > 0) {
496 os << " sibling-hit=0x" << asQosConfigHex(markSiblingHit);
497 }
498 if (markParentHit > 0) {
499 os << " parent-hit=0x" << asQosConfigHex(markParentHit);
500 }
501 if (markMiss > 0) {
502 os << " miss=0x" << asQosConfigHex(markMiss);
503 if (markMissMask!=0xFFFFFFFFU) {
504 os << "/0x" << asQosConfigHex(markMissMask);
505 }
506 }
507 if (preserveMissMark == false) {
508 os << " disable-preserve-miss";
509 }
510 if (preserveMissMark && preserveMissMarkMask != 0) {
511 os << " miss-mask=" << asQosConfigHex(preserveMissMarkMask);
512 }
513 os << "\n";
514 }
515}
516
517int
518Ip::Qos::setSockTos(const int fd, tos_t tos, int type)
519{
520 // Bug 3731: FreeBSD produces 'invalid option'
521 // unless we pass it a 32-bit variable storing 8-bits of data.
522 // NP: it is documented as 'int' for all systems, even those like Linux which accept 8-bit char
523 // so we convert to a int before setting.
524 int bTos = tos;
525
526 debugs(50, 3, "for FD " << fd << " to " << bTos);
527
528 if (type == AF_INET) {
529#if defined(IP_TOS)
530 const int x = xsetsockopt(fd, IPPROTO_IP, IP_TOS, &bTos, sizeof(bTos));
531 if (x < 0) {
532 int xerrno = errno;
533 debugs(50, 2, "setsockopt(IP_TOS) on " << fd << ": " << xstrerr(xerrno));
534 }
535 return x;
536#else
537 debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(IP_TOS) not supported on this platform");
538 return -1;
539#endif
540 } else { // type == AF_INET6
541#if defined(IPV6_TCLASS)
542 const int x = xsetsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &bTos, sizeof(bTos));
543 if (x < 0) {
544 int xerrno = errno;
545 debugs(50, 2, "setsockopt(IPV6_TCLASS) on " << fd << ": " << xstrerr(xerrno));
546 }
547 return x;
548#else
549 debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(IPV6_TCLASS) not supported on this platform");
550 return -1;
551#endif
552 }
553
554 /* CANNOT REACH HERE */
555}
556
557int
559{
560 const int x = Ip::Qos::setSockTos(conn->fd, tos, conn->remote.isIPv4() ? AF_INET : AF_INET6);
561 conn->tos = (x >= 0) ? tos : 0;
562 return x;
563}
564
565int
567{
568#if HAVE_LIBCAP && SO_MARK
569 debugs(50, 3, "for FD " << fd << " to " << mark);
570 const int x = xsetsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(nfmark_t));
571 if (x < 0) {
572 int xerrno = errno;
573 debugs(50, 2, "setsockopt(SO_MARK) on " << fd << ": " << xstrerr(xerrno));
574 }
575 return x;
576#elif HAVE_LIBCAP
577 (void)mark;
578 (void)fd;
579 debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(SO_MARK) not supported on this platform");
580 return -1;
581#else
582 (void)mark;
583 (void)fd;
584 debugs(50, DBG_IMPORTANT, "WARNING: Netfilter marking disabled (requires build --with-cap)");
585 return -1;
586#endif
587}
588
589int
591{
592 const int x = Ip::Qos::setSockNfmark(conn->fd, mark);
593 conn->nfmark = (x >= 0) ? mark : 0;
594 return x;
595}
596
597bool
599{
600 acl_nfmark * nfmarkAcls [] = { nfmarkToServer, nfmarkToClient };
601
602 for (int i=0; i<2; ++i) {
603 while (nfmarkAcls[i]) {
604 acl_nfmark *l = nfmarkAcls[i];
605 if (!l->markConfig.isEmpty())
606 return true;
607 nfmarkAcls[i] = l->next;
608 }
609 }
610
611 return false;
612}
613
614bool
616{
617 acl_tos * tosAcls [] = { tosToServer, tosToClient };
618
619 for (int i=0; i<2; ++i) {
620 while (tosAcls[i]) {
621 acl_tos *l = tosAcls[i];
622 if (l->tos > 0)
623 return true;
624 tosAcls[i] = l->next;
625 }
626 }
627
628 return false;
629}
630
631void
632dump_QosConfig(StoreEntry * const entry, const char * const directiveName, const Ip::Qos::Config &config)
633{
634 PackableStream os(*entry);
635 config.dumpConfigLine(os, directiveName);
636}
#define Assure(condition)
Definition Assure.h:35
#define Here()
source code location of the caller
Definition Here.h:15
AsHex< Integer > asHex(const Integer n)
a helper to ease AsHex object creation
Definition IoManip.h:169
void dump_QosConfig(StoreEntry *const entry, const char *const directiveName, const Ip::Qos::Config &config)
Definition QosConfig.cc:632
static auto asQosConfigHex(const Integer n)
helper function for printing Ip::Qos::Config mark and tos values
Definition QosConfig.cc:455
static char server[MAXLINE]
#define CBDATA_CLASS_INIT(type)
Definition cbdata.h:325
Ip::Address remote
Definition Connection.h:152
Ip::Address local
Definition Connection.h:149
nfmark_t nfConnmark
Definition Connection.h:174
static char * NextToken()
bool isIPv4() const
Definition Address.cc:178
bool isIPv6() const
Definition Address.cc:184
bool getInAddr(struct in_addr &) const
Definition Address.cc:1032
unsigned short port() const
Definition Address.cc:790
a netfilter mark/mask pair
nfmark_t applyToMark(nfmark_t m) const
bool isEmpty() const
whether the netfilter mark is unset
nfmark_t markParentHit
Netfilter mark value to apply to hits from parent.
Definition QosConfig.h:228
tos_t tosMiss
TOS value to apply to cache misses.
Definition QosConfig.h:221
bool isAclTosActive() const
Definition QosConfig.cc:615
nfmark_t markMiss
Netfilter mark value to apply to cache misses.
Definition QosConfig.h:229
tos_t preserveMissTosMask
The mask to apply when preserving the TOS of misses. Applies to preserved value from upstream.
Definition QosConfig.h:224
nfmark_t markMissMask
Mask for netfilter mark value to apply to cache misses. Applied to the markMiss value.
Definition QosConfig.h:230
nfmark_t preserveMissMarkMask
The mask to apply when preserving the netfilter mark of misses. Applied to preserved value from upstr...
Definition QosConfig.h:232
tos_t tosMissMask
Mask for TOS value to apply to cache misses. Applied to the tosMiss value.
Definition QosConfig.h:222
tos_t tosSiblingHit
TOS value to apply to hits from siblings.
Definition QosConfig.h:219
void parseConfigLine()
Definition QosConfig.cc:301
nfmark_t markSiblingHit
Netfilter mark value to apply to hits from siblings.
Definition QosConfig.h:227
tos_t tosParentHit
TOS value to apply to hits from parent.
Definition QosConfig.h:220
bool isAclNfmarkActive() const
Definition QosConfig.cc:598
void dumpConfigLine(std::ostream &, const char *) const
report configuration using qos_flows syntax
Definition QosConfig.cc:459
an std::runtime_error with thrower location info
acl_nfmark * next
Definition QosConfig.h:54
Ip::NfMarkConfig markConfig
Definition QosConfig.h:56
ACLList * aclList
Definition QosConfig.h:55
tos_t tos
Definition QosConfig.h:42
acl_tos * next
Definition QosConfig.h:40
ACLList * aclList
Definition QosConfig.h:41
Definition fde.h:52
tos_t tosFromServer
Definition fde.h:166
#define CMSG_LEN(len)
Definition cmsg.h:77
#define SQUID_CMSG_DATA(cmsg)
Definition cmsg.h:51
#define DBG_IMPORTANT
Definition Stream.h:38
#define debugs(SECTION, LEVEL, CONTENT)
Definition Stream.h:192
#define DBG_CRITICAL
Definition Stream.h:37
#define fd_table
Definition fde.h:189
void aclDestroyAclList(ACLList **list)
Definition Gadgets.cc:214
hier_code
Definition hier_code.h:12
@ PARENT_HIT
Definition hier_code.h:16
@ SIBLING_HIT
Definition hier_code.h:15
unsigned char tos_t
Definition forward.h:27
uint32_t nfmark_t
Definition forward.h:26
void getTosFromServer(const Comm::ConnectionPointer &server, fde *clientFde)
Definition QosConfig.cc:48
bool setNfConnmark(Comm::ConnectionPointer &conn, const ConnectionDirection connDir, const NfMarkConfig &cm)
Definition QosConfig.cc:186
ConnectionDirection
Possible Squid roles in connection handling.
Definition QosConfig.h:70
@ dirAccepted
accepted (from a client by Squid)
Definition QosConfig.h:71
int doNfmarkLocalHit(const Comm::ConnectionPointer &conn)
Definition QosConfig.cc:280
Config TheConfig
Globally available instance of Qos::Config.
Definition QosConfig.cc:288
int doTosLocalMiss(const Comm::ConnectionPointer &conn, const hier_code hierCode)
Definition QosConfig.cc:231
int setSockTos(const Comm::ConnectionPointer &conn, tos_t tos)
Definition QosConfig.cc:558
int doNfmarkLocalMiss(const Comm::ConnectionPointer &conn, const hier_code hierCode)
Definition QosConfig.cc:252
int doTosLocalHit(const Comm::ConnectionPointer &conn)
Definition QosConfig.cc:273
int setSockNfmark(const Comm::ConnectionPointer &conn, nfmark_t mark)
Definition QosConfig.cc:590
nfmark_t getNfConnmark(const Comm::ConnectionPointer &conn, const ConnectionDirection connDir)
Definition QosConfig.cc:151
Definition Xaction.cc:137
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
Definition Stream.h:63
int xgetsockopt(int socketFd, int level, int optionName, void *optionValue, socklen_t *optionLength)
POSIX getsockopt(2) equivalent.
Definition socket.h:92
int xsetsockopt(int socketFd, int level, int option, const void *value, socklen_t valueLength)
POSIX setsockopt(2) equivalent.
Definition socket.h:122
Definition cmsg.h:35
int cmsg_type
Definition cmsg.h:38
int cmsg_level
Definition cmsg.h:37
unsigned int cmsg_len
Definition cmsg.h:36
int socklen_t
Definition types.h:137
const char * xstrerr(int error)
Definition xstrerror.cc:83
bool xstrtoui(const char *s, char **end, unsigned int *value, unsigned int min, unsigned int max)
Definition xstrto.cc:86