]> git.ipfire.org Git - thirdparty/squid.git/blame - src/acl/ConnMark.cc
Added clientside_mark ACL for checking CONNMARK (#111)
[thirdparty/squid.git] / src / acl / ConnMark.cc
CommitLineData
653d9927
A
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/* DEBUG: section 28 Access Control */
10
11#include "squid.h"
12#include "acl/ConnMark.h"
13#include "acl/FilledChecklist.h"
14#include "client_side.h"
15#include "Debug.h"
16#include "http/Stream.h"
17#include "sbuf/Stream.h"
18
19bool
20Acl::ConnMark::empty() const
21{
22 return false;
23}
24
25static std::ostream &
26operator <<(std::ostream &os, const Acl::ConnMark::ConnMarkQuery connmark)
27{
28 os << asHex(connmark.first);
29 if (connmark.second != 0xffffffff) {
30 os << '/' << asHex(connmark.second);
31 }
32 return os;
33}
34
35nfmark_t
36Acl::ConnMark::getNumber(Parser::Tokenizer &tokenizer, const SBuf &token) const
37{
38 int64_t number;
39 if (!tokenizer.int64(number, 0, false)) {
40 throw TexcHere(ToSBuf("acl ", typeString(), ": invalid value '", tokenizer.buf(), "' in ", token));
41 }
42
43 if (number > std::numeric_limits<nfmark_t>::max()) {
44 throw TexcHere(ToSBuf("acl ", typeString(), ": number ", number, " in ", token, " is too big"));
45 }
46 return static_cast<nfmark_t>(number);
47}
48
49void
50Acl::ConnMark::parse()
51{
52 while (const char *t = ConfigParser::strtokFile()) {
53 SBuf token(t);
54 Parser::Tokenizer tokenizer(token);
55
56 const auto mark = getNumber(tokenizer, token);
57 const auto mask = tokenizer.skip('/') ? getNumber(tokenizer, token) : 0xffffffff;
58
59 if (!tokenizer.atEnd()) {
60 throw TexcHere(ToSBuf("acl ", typeString(), ": trailing garbage in ", token));
61 }
62
63 const ConnMarkQuery connmark(mark, mask);
64 marks.push_back(connmark);
65 debugs(28, 7, "added " << connmark);
66 }
67
68 if (marks.empty()) {
69 throw TexcHere(ToSBuf("acl ", typeString(), " requires at least one mark"));
70 }
71}
72
73int
74Acl::ConnMark::match(ACLChecklist *cl)
75{
76 const auto *checklist = Filled(cl);
77 const auto connmark = checklist->conn()->clientConnection->nfmark;
78
79 for (const auto &m : marks) {
80 if ((connmark & m.second) == m.first) {
81 debugs(28, 5, "found " << m << " matching " << asHex(connmark));
82 return 1;
83 }
84 debugs(28, 7, "skipped " << m << " mismatching " << asHex(connmark));
85 }
86 return 0;
87}
88
89SBufList
90Acl::ConnMark::dump() const
91{
92 SBufList sl;
93 for (const auto &m : marks) {
94 sl.push_back(ToSBuf(m));
95 }
96 return sl;
97}
98
99char const *
100Acl::ConnMark::typeString() const
101{
102 return "clientside_mark";
103}
104