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 
34 {
36  delete next;
37 }
38 
40 
42 {
44  delete next;
45 }
46 
47 void
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
91 
100 static int
101 getNfmarkCallback(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 
113 static nf_conntrack *
114 prepareConntrackQuery(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 
150 nfmark_t
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 
185 bool
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 
230 int
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 
251 int
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 
272 int
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 
279 int
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 
290 Ip::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 
300 void
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 
454 template <class Integer>
455 static auto asQosConfigHex(const Integer n) { return asHex(n).upperCase().minDigits(2); }
456 
458 void
459 Ip::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 
517 int
518 Ip::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 
557 int
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 
565 int
566 Ip::Qos::setSockNfmark(const int fd, nfmark_t mark)
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 
589 int
591 {
592  const int x = Ip::Qos::setSockNfmark(conn->fd, mark);
593  conn->nfmark = (x >= 0) ? mark : 0;
594  return x;
595 }
596 
597 bool
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 
614 bool
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 
631 void
632 dump_QosConfig(StoreEntry * const entry, const char * const directiveName, const Ip::Qos::Config &config)
633 {
634  PackableStream os(*entry);
635  config.dumpConfigLine(os, directiveName);
636 }
const char * xstrerr(int error)
Definition: xstrerror.cc:83
#define Here()
source code location of the caller
Definition: Here.h:15
bool isEmpty() const
whether the netfilter mark is unset
Definition: NfMarkConfig.h:35
#define DBG_CRITICAL
Definition: Stream.h:37
ACLList * aclList
Definition: QosConfig.h:41
bool xstrtoui(const char *s, char **end, unsigned int *value, unsigned int min, unsigned int max)
Definition: xstrto.cc:86
int setSockNfmark(const Comm::ConnectionPointer &conn, nfmark_t mark)
Definition: QosConfig.cc:590
int cmsg_type
Definition: cmsg.h:38
@ PARENT_HIT
Definition: hier_code.h:16
ACLList * aclList
Definition: QosConfig.h:55
unsigned int cmsg_len
Definition: cmsg.h:36
int doTosLocalMiss(const Comm::ConnectionPointer &conn, const hier_code hierCode)
Definition: QosConfig.cc:231
void getTosFromServer(const Comm::ConnectionPointer &server, fde *clientFde)
Definition: QosConfig.cc:48
nfmark_t markMissMask
Mask for netfilter mark value to apply to cache misses. Applied to the markMiss value.
Definition: QosConfig.h:230
tos_t tos
Definition: QosConfig.h:42
nfmark_t markSiblingHit
Netfilter mark value to apply to hits from siblings.
Definition: QosConfig.h:227
bool getInAddr(struct in_addr &) const
Definition: Address.cc:1040
const A & max(A const &lhs, A const &rhs)
unsigned char tos_t
Definition: forward.h:27
bool isIPv4() const
Definition: Address.cc:178
tos_t preserveMissTosMask
The mask to apply when preserving the TOS of misses. Applies to preserved value from upstream.
Definition: QosConfig.h:224
Definition: fde.h:51
int socklen_t
Definition: types.h:137
#define CMSG_LEN(len)
Definition: cmsg.h:77
@ SIBLING_HIT
Definition: hier_code.h:15
void dumpConfigLine(std::ostream &, const char *) const
report configuration using qos_flows syntax
Definition: QosConfig.cc:459
CBDATA_CLASS_INIT(acl_tos)
tos_t tosSiblingHit
TOS value to apply to hits from siblings.
Definition: QosConfig.h:219
nfmark_t preserveMissMarkMask
The mask to apply when preserving the netfilter mark of misses. Applied to preserved value from upstr...
Definition: QosConfig.h:232
unsigned short port() const
Definition: Address.cc:798
int doNfmarkLocalHit(const Comm::ConnectionPointer &conn)
Definition: QosConfig.cc:280
bool isIPv6() const
Definition: Address.cc:184
Ip::Address local
Definition: Connection.h:149
acl_tos * next
Definition: QosConfig.h:40
Config TheConfig
Definition: Config.cc:16
AsHex< Integer > asHex(const Integer n)
a helper to ease AsHex object creation
Definition: IoManip.h:169
int xsetsockopt(int socketFd, int level, int option, const void *value, socklen_t valueLength)
POSIX setsockopt(2) equivalent.
Definition: socket.h:122
tos_t tosFromServer
Definition: fde.h:166
Ip::Address remote
Definition: Connection.h:152
uint32_t nfmark_t
Definition: forward.h:26
nfmark_t nfConnmark
Definition: Connection.h:174
#define Assure(condition)
Definition: Assure.h:35
int cmsg_level
Definition: cmsg.h:37
static char * NextToken()
int xgetsockopt(int socketFd, int level, int optionName, void *optionValue, socklen_t *optionLength)
POSIX getsockopt(2) equivalent.
Definition: socket.h:92
Definition: Xaction.cc:137
void dump_QosConfig(StoreEntry *const entry, const char *const directiveName, const Ip::Qos::Config &config)
Definition: QosConfig.cc:632
#define fd_table
Definition: fde.h:189
ConnectionDirection
Possible Squid roles in connection handling.
Definition: QosConfig.h:70
Config TheConfig
Globally available instance of Qos::Config.
Definition: QosConfig.cc:288
nfmark_t markMiss
Netfilter mark value to apply to cache misses.
Definition: QosConfig.h:229
bool setNfConnmark(Comm::ConnectionPointer &conn, const ConnectionDirection connDir, const NfMarkConfig &cm)
nfmark_t getNfConnmark(const Comm::ConnectionPointer &conn, const ConnectionDirection connDir)
Definition: QosConfig.cc:151
int doNfmarkLocalMiss(const Comm::ConnectionPointer &conn, const hier_code hierCode)
Definition: QosConfig.cc:252
a netfilter mark/mask pair
Definition: NfMarkConfig.h:22
Definition: cmsg.h:35
an std::runtime_error with thrower location info
Definition: TextException.h:20
static char server[MAXLINE]
tos_t tosMissMask
Mask for TOS value to apply to cache misses. Applied to the tosMiss value.
Definition: QosConfig.h:222
acl_nfmark * next
Definition: QosConfig.h:54
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
Definition: Stream.h:63
#define DBG_IMPORTANT
Definition: Stream.h:38
hier_code
Definition: hier_code.h:12
int setSockTos(const Comm::ConnectionPointer &conn, tos_t tos)
Definition: QosConfig.cc:558
@ dirAccepted
accepted (from a client by Squid)
Definition: QosConfig.h:71
Ip::NfMarkConfig markConfig
Definition: QosConfig.h:56
int doTosLocalHit(const Comm::ConnectionPointer &conn)
Definition: QosConfig.cc:273
static auto asQosConfigHex(const Integer n)
helper function for printing Ip::Qos::Config mark and tos values
Definition: QosConfig.cc:455
tos_t tosParentHit
TOS value to apply to hits from parent.
Definition: QosConfig.h:220
void parseConfigLine()
Definition: QosConfig.cc:301
void aclDestroyAclList(ACLList **list)
Definition: Gadgets.cc:214
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
int EnableIpv6
Whether IPv6 is supported and type of support.
Definition: tools.h:25
nfmark_t applyToMark(nfmark_t m) const
Definition: NfMarkConfig.cc:46
bool isAclTosActive() const
Definition: QosConfig.cc:615
~acl_tos()
Definition: QosConfig.cc:33
bool isAclNfmarkActive() const
Definition: QosConfig.cc:598
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
#define SQUID_CMSG_DATA(cmsg)
Definition: cmsg.h:51
nfmark_t nfmark
Definition: Connection.h:166

 

Introduction

Documentation

Support

Miscellaneous