ipcache.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2017 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_IPCACHE_H
10 #define _SQUID_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  virtual ~IpReceiver() {}
198 
202  virtual void noteIps(const CachedIps *ips, const LookupDetails &details) = 0;
203 
205  virtual void noteIp(const Ip::Address &) {}
206 
209  virtual void noteLookup(const Dns::LookupDetails &) {}
210 };
211 
213 void nbgethostbyname(const char *name, const CbcPointer<IpReceiver> &receiver);
214 
215 } // namespace Dns
216 
218 
219 typedef void IPH(const ipcache_addrs *, const Dns::LookupDetails &details, void *);
220 
221 void ipcache_purgelru(void *);
222 void ipcache_nbgethostbyname(const char *name, IPH * handler, void *handlerData);
223 const ipcache_addrs *ipcache_gethostbyname(const char *, int flags);
224 void ipcacheInvalidate(const char *);
225 void ipcacheInvalidateNegative(const char *);
226 void ipcache_init(void);
227 void ipcacheMarkBadAddr(const char *name, const Ip::Address &);
228 void ipcacheMarkGoodAddr(const char *name, const Ip::Address &);
229 void ipcacheFreeMemory(void);
230 void ipcache_restart(void);
231 int ipcacheAddEntryFromHosts(const char *name, const char *ipaddr);
232 
233 inline std::ostream &
234 operator <<(std::ostream &os, const Dns::CachedIps &ips)
235 {
236  ips.reportCurrent(os);
237  return os;
238 }
239 
240 /* inlined implementations */
241 
244 {
245  return IpsSelector<GoodIpsIterator>(*this);
246 }
247 
250 {
251  return IpsSelector<IpsIterator>(*this);
252 }
253 
254 #endif /* _SQUID_IPCACHE_H */
255 
std::ostream & operator<<(std::ostream &os, const Dns::CachedIps &ips)
Definition: ipcache.h:234
pointer operator->() const
Definition: ipcache.h:128
Iterates over good IPs in CachedIps, starting at the so called current one.
Definition: ipcache.h:141
Dns::CachedIps ipcache_addrs
deprecated alias
Definition: ipcache.h:217
reference operator*() const
Definition: ipcache.h:157
bool bad() const
whether the address is currently deemed problematic for any reason
Definition: ipcache.h:29
an interface for receiving IP::Addresses from nbgethostbyname()
Definition: ipcache.h:194
Iterator begin() const noexcept
Definition: ipcache.h:186
Raw::const_iterator RawIterator
Definition: ipcache.h:115
void forgetMarking(const char *name, const Ip::Address &ip)
undo successful markAsBad()
Definition: ipcache.cc:1031
IpsSelector< GoodIpsIterator > good() const
good IPs
Definition: ipcache.h:243
void forgetMarking()
undo markAsBad()
Definition: ipcache.h:35
IpsIterator(const Raw &raw, const size_t)
Definition: ipcache.h:123
reference operator*() const
Definition: ipcache.h:127
Iterator cend() const noexcept
Definition: ipcache.h:185
size_t processed_
number of visited positions, including skipped ones
Definition: ipcache.h:173
IpsSelector(const CachedIps &ips)
Definition: ipcache.h:182
encapsulates DNS lookup results
Definition: LookupDetails.h:20
CachedIp(const Ip::Address &anIp)
Definition: ipcache.h:26
std::forward_iterator_tag iterator_category
Definition: ipcache.h:118
value_type * pointer
Definition: ipcache.h:120
size_t size() const noexcept
all cached IPs
Definition: ipcache.h:62
bool operator==(const GoodIpsIterator them) const
Definition: ipcache.h:163
const Storage & raw() const
all cached entries
Definition: ipcache.h:69
const Ip::Address value_type
Definition: ipcache.h:149
std::vector< CachedIp > Raw
Definition: ipcache.h:114
static MemPoolIterator Iterator
Definition: Pool.cc:26
bool have(const Ip::Address &ip, size_t *position=nullptr) const
Definition: ipcache.cc:974
a CachedIps element
Definition: ipcache.h:23
const CachedIp & current() const
Definition: ipcache.h:167
IpsIterator(const Raw &raw)
Definition: ipcache.h:125
size_t position_
current iteration location, modulo raw.size()
Definition: ipcache.h:172
pointer operator->() const
Definition: ipcache.h:158
void ipcacheInvalidate(const char *)
Definition: ipcache.cc:856
void reset(const Ip::Address &ip)
replace all info with the given (presumed good) IP address
Definition: ipcache.cc:948
size_t badCount_
number of IPs that are currently marked as bad
Definition: ipcache.h:101
void pushUnique(const Ip::Address &ip)
Definition: ipcache.cc:992
const CachedIps & ips_
master IP storage we are wrapping
Definition: ipcache.h:190
void ipcacheMarkGoodAddr(const char *name, const Ip::Address &)
Definition: ipcache.cc:1066
void nbgethostbyname(const char *name, const CbcPointer< IpReceiver > &receiver)
initiate an (often) asynchronous DNS lookup; the receiver gets the results
Definition: ipcache.cc:607
GoodIpsIterator & operator++()
Definition: ipcache.h:160
void ipcacheMarkBadAddr(const char *name, const Ip::Address &)
Definition: ipcache.cc:1058
void ipcache_nbgethostbyname(const char *name, IPH *handler, void *handlerData)
Definition: ipcache.cc:600
Raw::const_iterator RawIterator
Definition: ipcache.h:145
static void handler(int signo)
Definition: purge.cc:860
std::forward_iterator_tag iterator_category
Definition: ipcache.h:148
RawIterator position_
current iteration location
Definition: ipcache.h:137
Iterates over any (good and/or bad) IPs in CachedIps, in unspecified order.
Definition: ipcache.h:111
const Ip::Address value_type
Definition: ipcache.h:119
GoodIpsIterator(const Raw &raw, const size_t currentPos)
Definition: ipcache.h:153
GoodIpsIterator(const Raw &raw)
Definition: ipcache.h:155
value_type * pointer
Definition: ipcache.h:150
const ipcache_addrs * ipcache_gethostbyname(const char *, int flags)
Definition: ipcache.cc:720
virtual ~IpReceiver()
Definition: ipcache.h:197
void restoreGoodness(const char *name)
makes current() calls possible after a successful markAsBad()
Definition: ipcache.cc:960
virtual void noteLookup(const Dns::LookupDetails &)
Definition: ipcache.h:209
Storage ips
good and bad IPs
Definition: ipcache.h:97
Ip::Address ip
Definition: ipcache.h:37
bool bad_
whether the address is currently deemed problematic
Definition: ipcache.h:40
bool seekNewGood(const char *name)
Definition: ipcache.cc:931
int ipcacheAddEntryFromHosts(const char *name, const char *ipaddr)
Definition: ipcache.cc:1124
size_t goodPosition
position of the IP returned by current()
Definition: ipcache.h:100
bool operator==(const IpsIterator them) const
Definition: ipcache.h:133
value_type & reference
Definition: ipcache.h:151
void ipcache_purgelru(void *)
Definition: ipcache.cc:351
void reportCurrent(std::ostream &os) const
prints current IP and other debugging information
Definition: ipcache.cc:1000
std::vector< CachedIp > Storage
Definition: ipcache.h:68
value_type & reference
Definition: ipcache.h:121
GoodIpsIterator operator++(int)
Definition: ipcache.h:161
const Raw & raw_
CachedIps being iterated.
Definition: ipcache.h:171
void IPH(const ipcache_addrs *, const Dns::LookupDetails &details, void *)
Definition: ipcache.h:219
std::vector< CachedIp > Raw
Definition: ipcache.h:144
void ipcacheFreeMemory(void)
Definition: ipcache.cc:1088
void ipcache_init(void)
Definition: ipcache.cc:687
IpsIterator & operator++()
Definition: ipcache.h:130
virtual void noteIp(const Ip::Address &)
Called when/if nbgethostbyname() discovers a new good IP address.
Definition: ipcache.h:205
bool operator!=(const GoodIpsIterator them) const
Definition: ipcache.h:164
void markAsBad()
mark the address as problematic; it might already be marked
Definition: ipcache.h:32
bool operator!=(const IpsIterator them) const
Definition: ipcache.h:134
const Ip::Address & current() const
Definition: ipcache.h:59
IpsSelector< IpsIterator > goodAndBad() const
all IPs
Definition: ipcache.h:249
virtual void noteIps(const CachedIps *ips, const LookupDetails &details)=0
int size
Definition: ModDevPoll.cc:77
size_t badCount() const noexcept
bad IPs
Definition: ipcache.h:63
void markAsBad(const char *name, const Ip::Address &ip)
Definition: ipcache.cc:1011
void ipcacheInvalidateNegative(const char *)
Definition: ipcache.cc:873
Iterator end() const noexcept
Definition: ipcache.h:187
bool empty() const noexcept
whether we cached no IPs at all
Definition: ipcache.h:61
Iterator cbegin() const noexcept
Definition: ipcache.h:184
IpsIterator operator++(int)
Definition: ipcache.h:131
void ipcache_restart(void)
Definition: ipcache.cc:1103

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors