ipcache.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 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 #ifndef SQUID_SRC_IPCACHE_H
10 #define SQUID_SRC_IPCACHE_H
11 
12 #include "base/CbcPointer.h"
13 #include "dns/forward.h"
14 #include "ip/Address.h"
15 #include <iosfwd>
16 #include <vector>
17 
18 // The IPs the caller should not connect to are "bad". Other IPs are "good".
19 
20 namespace Dns {
21 
23 class CachedIp
24 {
25 public:
26  explicit CachedIp(const Ip::Address &anIp): ip(anIp) {}
27 
29  bool bad() const { return bad_; }
30 
32  void markAsBad() { bad_ = true; }
33 
35  void forgetMarking() { bad_ = false; }
36 
38 
39 private:
40  bool bad_ = false;
41 };
42 
43 class IpsIterator;
44 class GoodIpsIterator;
45 template <class Iterator>
47 
50 class CachedIps
51 {
52 public:
55  bool have(const Ip::Address &ip, size_t *position = nullptr) const;
56 
59  const Ip::Address &current() const { return ips.at(goodPosition).ip; }
60 
61  bool empty() const noexcept { return ips.empty(); }
62  size_t size() const noexcept { return ips.size(); }
63  size_t badCount() const noexcept { return badCount_; }
64 
65  inline IpsSelector<GoodIpsIterator> good() const;
66  inline IpsSelector<IpsIterator> goodAndBad() const;
67 
68  typedef std::vector<CachedIp> Storage;
69  const Storage &raw() const { return ips; }
70 
75  void markAsBad(const char *name, const Ip::Address &ip);
76 
78  void forgetMarking(const char *name, const Ip::Address &ip);
79 
82  void pushUnique(const Ip::Address &ip);
83 
85  void reset(const Ip::Address &ip);
86 
88  void reportCurrent(std::ostream &os) const;
89 
90 private:
91  bool seekNewGood(const char *name);
92  void restoreGoodness(const char *name);
93 
94  // Memory- and speed-optimized for "a few (and usually just one)" IPs,
95  // the vast majority of which are "good". The current implementation
96  // does linear searches and often reallocs when adding IPs.
98 
99  template <class Iterator> friend class IpsSelector;
100  size_t goodPosition = 0;
101  size_t badCount_ = 0;
102 };
103 
104 // The CachedIps class keeps meta information about individual IP addresses
105 // together with those IPs. CachedIps users do not care about caching details;
106 // they just want to iterate (a subset of) cached IPs. The IpsIterator and
107 // IpsSelector classes below are minimal helper classes that make cached IPs
108 // iteration easier, safer, and copy-free. See also: CachedIps::good().
109 
112 {
113 public:
114  typedef std::vector<CachedIp> Raw;
115  typedef Raw::const_iterator RawIterator;
116 
117  // some of the standard iterator traits
118  using iterator_category = std::forward_iterator_tag;
119  using value_type = const Ip::Address;
120  using pointer = value_type *;
122 
123  IpsIterator(const Raw &raw, const size_t): position_(raw.cbegin()) {}
124  // special constructor for end() iterator
125  explicit IpsIterator(const Raw &raw): position_(raw.cend()) {}
126 
127  reference operator *() const { return position_->ip; }
128  pointer operator ->() const { return &position_->ip; }
129 
130  IpsIterator& operator++() { ++position_; return *this; }
131  IpsIterator operator++(int) { const auto oldMe = *this; ++(*this); return oldMe; }
132 
133  bool operator ==(const IpsIterator them) const { return position_ == them.position_; }
134  bool operator !=(const IpsIterator them) const { return !(*this == them); }
135 
136 private:
138 };
139 
142 {
143 public:
144  typedef std::vector<CachedIp> Raw;
145  typedef Raw::const_iterator RawIterator;
146 
147  // some of the standard iterator traits
148  using iterator_category = std::forward_iterator_tag;
149  using value_type = const Ip::Address;
150  using pointer = value_type *;
152 
153  GoodIpsIterator(const Raw &raw, const size_t currentPos): raw_(raw), position_(currentPos), processed_(0) { sync(); }
154  // special constructor for end() iterator
155  explicit GoodIpsIterator(const Raw &raw): raw_(raw), position_(0), processed_(raw.size()) {}
156 
157  reference operator *() const { return current().ip; }
158  pointer operator ->() const { return &current().ip; }
159 
160  GoodIpsIterator& operator++() { next(); sync(); return *this; }
161  GoodIpsIterator operator++(int) { const auto oldMe = *this; ++(*this); return oldMe; }
162 
163  bool operator ==(const GoodIpsIterator them) const { return processed_ == them.processed_; }
164  bool operator !=(const GoodIpsIterator them) const { return !(*this == them); }
165 
166 private:
167  const CachedIp &current() const { return raw_[position_ % raw_.size()]; }
168  void next() { ++position_; ++processed_; }
169  void sync() { while (processed_ < raw_.size() && current().bad()) next(); }
170 
171  const Raw &raw_;
172  size_t position_;
173  size_t processed_;
174 };
175 
178 template <class Iterator>
179 class IpsSelector
180 {
181 public:
182  explicit IpsSelector(const CachedIps &ips): ips_(ips) {}
183 
184  Iterator cbegin() const noexcept { return Iterator(ips_.raw(), ips_.goodPosition); }
185  Iterator cend() const noexcept { return Iterator(ips_.raw()); }
186  Iterator begin() const noexcept { return cbegin(); }
187  Iterator end() const noexcept { return cend(); }
188 
189 private:
190  const CachedIps &ips_;
191 };
192 
194 class IpReceiver: public virtual CbdataParent
195 {
196 public:
197  ~IpReceiver() override {}
198 
203  virtual void noteIps(const CachedIps *ips, const LookupDetails &details) = 0;
204 
206  virtual void noteIp(const Ip::Address &) {}
207 
210  virtual void noteLookup(const Dns::LookupDetails &) {}
211 };
212 
214 void nbgethostbyname(const char *name, const CbcPointer<IpReceiver> &receiver);
215 
216 inline std::ostream &
217 operator <<(std::ostream &os, const CachedIps &ips)
218 {
219  ips.reportCurrent(os);
220  return os;
221 }
222 
223 } // namespace Dns
224 
226 
227 typedef void IPH(const ipcache_addrs *, const Dns::LookupDetails &details, void *);
228 
229 void ipcache_purgelru(void *);
230 void ipcache_nbgethostbyname(const char *name, IPH * handler, void *handlerData);
231 const ipcache_addrs *ipcache_gethostbyname(const char *, int flags);
232 void ipcacheInvalidate(const char *);
233 void ipcacheInvalidateNegative(const char *);
234 void ipcache_init(void);
235 void ipcacheMarkBadAddr(const char *name, const Ip::Address &);
236 void ipcacheMarkGoodAddr(const char *name, const Ip::Address &);
237 void ipcache_restart(void);
238 int ipcacheAddEntryFromHosts(const char *name, const char *ipaddr);
239 
240 /* inlined implementations */
241 
244 {
245  return IpsSelector<GoodIpsIterator>(*this);
246 }
247 
250 {
251  return IpsSelector<IpsIterator>(*this);
252 }
253 
254 #endif /* SQUID_SRC_IPCACHE_H */
255 
CachedIp(const Ip::Address &anIp)
Definition: ipcache.h:26
void markAsBad(const char *name, const Ip::Address &ip)
Definition: ipcache.cc:1022
void forgetMarking()
undo markAsBad()
Definition: ipcache.h:35
a CachedIps element
Definition: ipcache.h:23
bool operator!=(const IpsIterator them) const
Definition: ipcache.h:134
size_t goodPosition
position of the IP returned by current()
Definition: ipcache.h:100
reference operator*() const
Definition: ipcache.h:157
Raw::const_iterator RawIterator
Definition: ipcache.h:145
pointer operator->() const
Definition: ipcache.h:128
const Raw & raw_
CachedIps being iterated.
Definition: ipcache.h:171
value_type * pointer
Definition: ipcache.h:120
void ipcacheInvalidate(const char *)
Definition: ipcache.cc:865
reference operator*() const
Definition: ipcache.h:127
size_t badCount_
number of IPs that are currently marked as bad
Definition: ipcache.h:101
void ipcacheInvalidateNegative(const char *)
Definition: ipcache.cc:882
std::forward_iterator_tag iterator_category
Definition: ipcache.h:118
pointer operator->() const
Definition: ipcache.h:158
value_type & reference
Definition: ipcache.h:151
GoodIpsIterator(const Raw &raw, const size_t currentPos)
Definition: ipcache.h:153
const ipcache_addrs * ipcache_gethostbyname(const char *, int flags)
Definition: ipcache.cc:729
bool operator!=(const GoodIpsIterator them) const
Definition: ipcache.h:164
bool have(const Ip::Address &ip, size_t *position=nullptr) const
Definition: ipcache.cc:984
Iterator begin() const noexcept
Definition: ipcache.h:186
int ipcacheAddEntryFromHosts(const char *name, const char *ipaddr)
Definition: ipcache.cc:1126
const Ip::Address & current() const
Definition: ipcache.h:59
void ipcache_restart(void)
Definition: ipcache.cc:1105
GoodIpsIterator & operator++()
Definition: ipcache.h:160
IpsIterator(const Raw &raw, const size_t)
Definition: ipcache.h:123
Iterator cend() const noexcept
Definition: ipcache.h:185
bool operator==(const GoodIpsIterator them) const
Definition: ipcache.h:163
const CachedIps & ips_
master IP storage we are wrapping
Definition: ipcache.h:190
std::vector< CachedIp > Storage
Definition: ipcache.h:68
size_t position_
current iteration location, modulo raw.size()
Definition: ipcache.h:172
~IpReceiver() override
Definition: ipcache.h:197
IpsSelector(const CachedIps &ips)
Definition: ipcache.h:182
GoodIpsIterator(const Raw &raw)
Definition: ipcache.h:155
an interface for receiving IP::Addresses from nbgethostbyname()
Definition: ipcache.h:194
int size
Definition: ModDevPoll.cc:69
void nbgethostbyname(const char *name, const CbcPointer< IpReceiver > &receiver)
initiate an (often) asynchronous DNS lookup; the receiver gets the results
Definition: ipcache.cc:616
Dns::CachedIps ipcache_addrs
deprecated alias
Definition: ipcache.h:225
bool bad() const
whether the address is currently deemed problematic for any reason
Definition: ipcache.h:29
generic DNS API
Definition: forward.h:20
std::ostream & operator<<(std::ostream &os, const LookupDetails &dns)
Definition: LookupDetails.h:44
void ipcache_nbgethostbyname(const char *name, IPH *handler, void *handlerData)
Definition: ipcache.cc:609
std::vector< CachedIp > Raw
Definition: ipcache.h:114
virtual void noteLookup(const Dns::LookupDetails &)
Definition: ipcache.h:210
void markAsBad()
mark the address as problematic; it might already be marked
Definition: ipcache.h:32
std::forward_iterator_tag iterator_category
Definition: ipcache.h:148
void pushUnique(const Ip::Address &ip)
Definition: ipcache.cc:1003
const CachedIp & current() const
Definition: ipcache.h:167
encapsulates DNS lookup results
Definition: LookupDetails.h:22
IpsIterator(const Raw &raw)
Definition: ipcache.h:125
void ipcacheMarkGoodAddr(const char *name, const Ip::Address &)
Definition: ipcache.cc:1077
Storage ips
good and bad IPs
Definition: ipcache.h:97
value_type & reference
Definition: ipcache.h:121
void reportCurrent(std::ostream &os) const
prints current IP and other debugging information
Definition: ipcache.cc:1011
size_t processed_
number of visited positions, including skipped ones
Definition: ipcache.h:173
RawIterator position_
current iteration location
Definition: ipcache.h:137
void ipcache_init(void)
Definition: ipcache.cc:696
bool bad_
whether the address is currently deemed problematic
Definition: ipcache.h:40
virtual void noteIp(const Ip::Address &)
Called when/if nbgethostbyname() discovers a new good IP address.
Definition: ipcache.h:206
const Ip::Address value_type
Definition: ipcache.h:149
void restoreGoodness(const char *name)
makes current() calls possible after a successful markAsBad()
Definition: ipcache.cc:969
void forgetMarking(const char *name, const Ip::Address &ip)
undo successful markAsBad()
Definition: ipcache.cc:1042
bool operator==(const IpsIterator them) const
Definition: ipcache.h:133
const Ip::Address value_type
Definition: ipcache.h:119
bool seekNewGood(const char *name)
Definition: ipcache.cc:940
void reset(const Ip::Address &ip)
replace all info with the given (presumed good) IP address
Definition: ipcache.cc:957
IpsIterator operator++(int)
Definition: ipcache.h:131
Iterates over good IPs in CachedIps, starting at the so called current one.
Definition: ipcache.h:141
GoodIpsIterator operator++(int)
Definition: ipcache.h:161
std::vector< CachedIp > Raw
Definition: ipcache.h:144
IpsIterator & operator++()
Definition: ipcache.h:130
void ipcache_purgelru(void *)
Definition: ipcache.cc:353
void ipcacheMarkBadAddr(const char *name, const Ip::Address &)
Definition: ipcache.cc:1069
Iterator end() const noexcept
Definition: ipcache.h:187
Ip::Address ip
Definition: ipcache.h:37
value_type * pointer
Definition: ipcache.h:150
Iterator cbegin() const noexcept
Definition: ipcache.h:184
Raw::const_iterator RawIterator
Definition: ipcache.h:115
virtual void noteIps(const CachedIps *ips, const LookupDetails &details)=0
void IPH(const ipcache_addrs *, const Dns::LookupDetails &details, void *)
Definition: ipcache.h:227
Iterates over any (good and/or bad) IPs in CachedIps, in unspecified order.
Definition: ipcache.h:111
IpsSelector< GoodIpsIterator > good() const
good IPs
Definition: ipcache.h:243
IpsSelector< IpsIterator > goodAndBad() const
all IPs
Definition: ipcache.h:249

 

Introduction

Documentation

Support

Miscellaneous