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

 

Introduction

Documentation

Support

Miscellaneous