]>
Commit | Line | Data |
---|---|---|
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 | ||
19 | bool | |
20 | Acl::ConnMark::empty() const | |
21 | { | |
22 | return false; | |
23 | } | |
24 | ||
25 | static std::ostream & | |
26 | operator <<(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 | ||
35 | nfmark_t | |
36 | Acl::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 | ||
49 | void | |
50 | Acl::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 | ||
73 | int | |
74 | Acl::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 | ||
89 | SBufList | |
90 | Acl::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 | ||
99 | char const * | |
100 | Acl::ConnMark::typeString() const | |
101 | { | |
102 | return "clientside_mark"; | |
103 | } | |
104 |