]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/Random.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / acl / Random.cc
1 /*
2 * Copyright (C) 1996-2020 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/FilledChecklist.h"
13 #include "acl/Random.h"
14 #include "Debug.h"
15 #include "Parsing.h"
16 #include "wordlist.h"
17
18 #include <random>
19
20 ACL *
21 ACLRandom::clone() const
22 {
23 return new ACLRandom(*this);
24 }
25
26 ACLRandom::ACLRandom(char const *theClass) : data(0.0), class_(theClass)
27 {
28 memset(pattern, 0, sizeof(pattern));
29 }
30
31 ACLRandom::ACLRandom(ACLRandom const & old) : data(old.data), class_(old.class_)
32 {
33 memcpy(pattern, old.pattern, sizeof(pattern));
34 }
35
36 ACLRandom::~ACLRandom()
37 { }
38
39 char const *
40 ACLRandom::typeString() const
41 {
42 return class_;
43 }
44
45 bool
46 ACLRandom::empty () const
47 {
48 return data == 0.0;
49 }
50
51 bool
52 ACLRandom::valid() const
53 {
54 return !empty();
55 }
56
57 /*******************/
58 /* aclParseRandomList */
59 /*******************/
60 void
61 ACLRandom::parse()
62 {
63 char bufa[256], bufb[256];
64
65 char *t = ConfigParser::strtokFile();
66 if (!t) {
67 debugs(28, DBG_PARSE_NOTE(DBG_IMPORTANT), "ACL random missing pattern");
68 return;
69 }
70
71 debugs(28, 5, "aclParseRandomData: " << t);
72
73 // seed random generator ...
74 srand(time(NULL));
75
76 if (sscanf(t, "%[0-9]:%[0-9]", bufa, bufb) == 2) {
77 int a = xatoi(bufa);
78 int b = xatoi(bufb);
79 if (a <= 0 || b <= 0) {
80 debugs(28, DBG_CRITICAL, "ERROR: ACL random with bad pattern: '" << t << "'");
81 return;
82 } else
83 data = a / (double)(a+b);
84 } else if (sscanf(t, "%[0-9]/%[0-9]", bufa, bufb) == 2) {
85 int a = xatoi(bufa);
86 int b = xatoi(bufb);
87 if (a <= 0 || b <= 0 || a > b) {
88 debugs(28, DBG_CRITICAL, "ERROR: ACL random with bad pattern: '" << t << "'");
89 return;
90 } else
91 data = (double) a / (double) b;
92 } else if (sscanf(t, "0.%[0-9]", bufa) == 1) {
93 data = atof(t);
94 } else {
95 debugs(28, DBG_CRITICAL, "ERROR: ACL random with bad pattern: '" << t << "'");
96 return;
97 }
98
99 // save the exact input pattern. so we can display it later.
100 memcpy(pattern, t, min(sizeof(pattern)-1,strlen(t)));
101 }
102
103 int
104 ACLRandom::match(ACLChecklist *)
105 {
106 // make up the random value.
107 // The fixed-value default seed is fine because we are
108 // actually matching whether the random value is above
109 // or below the configured threshold ratio.
110 static std::mt19937 mt;
111 static xuniform_real_distribution<> dist(0, 1);
112
113 const double random = dist(mt);
114
115 debugs(28, 3, "ACL Random: " << name << " " << pattern << " test: " << data << " > " << random << " = " << ((data > random)?"MATCH":"NO MATCH") );
116 return (data > random)?1:0;
117 }
118
119 SBufList
120 ACLRandom::dump() const
121 {
122 SBufList sl;
123 sl.push_back(SBuf(pattern));
124 return sl;
125 }
126