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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors