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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors