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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors