E-MailRelay

gdnsblock.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 Graeme Walker <graeme_walker@users.sourceforge.net>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file gdnsblock.h
19///
20
21#ifndef G_NET_DNS_BLOCK_H
22#define G_NET_DNS_BLOCK_H
23
24#include "gdef.h"
25#include "gaddress.h"
26#include "gdatetime.h"
27#include "geventhandler.h"
28#include "gexceptionsink.h"
29#include "gexception.h"
30#include "gstrings.h"
31#include "gtimer.h"
32#include "gsocket.h"
33#include <vector>
34
35 namespace GNet
36{
37 class DnsBlock ;
38 class DnsBlockResult ;
39 class DnsBlockServerResult ;
40 class DnsBlockCallback ;
41}
42
43//| \class GNet::DnsBlockServerResult
44/// A result structure for one DNSBL server.
45///
46 class GNet::DnsBlockServerResult
47{
48 public:
49 explicit DnsBlockServerResult( const std::string & server ) ;
50 ///< Constructor.
51
52 void set( const std::vector<Address> & ) ;
53 ///< Sets the result list().
54
55 bool valid() const ;
56 ///< Returns true if the list() is valid.
57
58 std::string server() const ;
59 ///< Returns the server.
60
61 const std::vector<Address> & addresses() const ;
62 ///< Returns the result list, which is empty if
63 ///< there is no block or not valid().
64
65 private:
66 std::string m_server ;
67 bool m_valid ;
68 std::vector<Address> m_addresses ;
69} ;
70
71//| \class GNet::DnsBlockResult
72/// A result structure for GNet::DnsBlock, as delivered by the
73/// DnsBlockCallback interface. The principal attribute is the
74/// type(), which indicates whether the connection should be
75/// allowed or denied.
76///
77 class GNet::DnsBlockResult
78{
79 public:
80 enum class Type
81 {
82 Inactive , // no configured servers
83 Local , // local address not checked
84 TimeoutAllow , // not all responses in the timeout period
85 TimeoutDeny , // not enough responses in the timeout period
86 Allow , // below threshold of deny responses
87 Deny // threshold of deny responses
88 } ;
89
90 public:
91 DnsBlockResult() ;
92 ///< Constructor.
93
94 void reset( std::size_t threshold , const Address & ) ;
95 ///< Initialiser.
96
97 void add( const DnsBlockServerResult & ) ;
98 ///< Appends the server result.
99
100 DnsBlockServerResult & at( std::size_t ) ;
101 ///< Returns a reference to the given per-server result.
102
103 Type & type() ;
104 ///< Returns a settable reference to the overall result type.
105
106 void log() const ;
107 ///< Logs the results.
108
109 void warn() const ;
110 ///< Emits warnings.
111
112 bool allow() const ;
113 ///< Returns true if the type is Inactive, Local, TimeoutAllow or Allow.
114
115 bool deny() const ;
116 ///< Returns true if the type is TimeoutDeny or Deny.
117
118 const std::vector<DnsBlockServerResult> & list() const ;
119 ///< Returns a reference to the per-server results.
120
121 G::StringArray deniers() const ;
122 ///< Returns the list of denying servers.
123
124 G::StringArray laggards() const ;
125 ///< Returns the list of slow or unresponsive servers.
126
127 private:
128 using ResultList = std::vector<DnsBlockServerResult> ;
129 Type m_type{Type::Inactive} ;
130 std::size_t m_threshold{0U} ;
131 Address m_address ;
132 ResultList m_list ;
133} ;
134
135//| \class GNet::DnsBlock
136/// Implements DNS blocklisting, as per RFC-5782. The implementation
137/// sends DNS requests for each configured block-list server
138/// incorporating the IP address to be tested, for example
139/// "1.0.0.127.nospam.com" and "1.0.0.127.blockme.org". All requests
140/// go to the same DNS server and are cached or routed in the
141/// normal way, so the block-list servers are not contacted
142/// directly.
143///
144 class GNet::DnsBlock : private EventHandler
145{
146 public:
147 G_EXCEPTION( Error , "dnsbl error" ) ;
148 using ResultList = std::vector<DnsBlockServerResult> ;
149
150 DnsBlock( DnsBlockCallback & , ExceptionSink , const std::string & config = std::string() ) ;
151 ///< Constructor. Use configure() if necessary and then start(),
152 ///< one time only.
153
154 void configure( const Address & dns_server , std::size_t threshold , bool allow_on_timeout ,
155 G::TimeInterval timeout , const G::StringArray & servers ) ;
156 ///< Configures the object after construction.
157
158 void configure( const std::string & ) ;
159 ///< Configuration overload taking a configuration string containing
160 ///< comma-separated fields of: dns-server-address, timeout-ms,
161 ///< threshold, dnsbl-server-list.
162
163 static void checkConfig( const std::string & ) ;
164 ///< Checks the configure() string, throwing on error.
165
166 void start( const Address & ) ;
167 ///< Starts an asychronous check on the given address. The result
168 ///< is delivered via the callback interface passed to the ctor.
169
170 bool busy() const ;
171 ///< Returns true after start() and before the completion callback.
172
173 public:
174 ~DnsBlock() override = default ;
175 DnsBlock( const DnsBlock & ) = delete ;
176 DnsBlock( DnsBlock && ) = delete ;
177 void operator=( const DnsBlock & ) = delete ;
178 void operator=( DnsBlock && ) = delete ;
179
180 private: // overrides
181 void readEvent() override ; // Override from GNet::EventHandler.
182
183 private:
184 static void configureImp( const std::string & , DnsBlock * ) ;
185 void onTimeout() ;
186 static std::string queryString( const Address & ) ;
187 static std::size_t countResponders( const ResultList & ) ;
188 static std::size_t countDeniers( const ResultList & ) ;
189
190 private:
191 DnsBlockCallback & m_callback ;
192 ExceptionSink m_es ;
193 Timer<DnsBlock> m_timer ;
194 G::StringArray m_servers ;
195 std::size_t m_threshold ;
196 bool m_allow_on_timeout ;
197 Address m_dns_server ;
198 G::TimeInterval m_timeout ;
199 DnsBlockResult m_result ;
200 unsigned int m_id_base ;
201 std::unique_ptr<DatagramSocket> m_socket_ptr ;
202} ;
203
204//| \class GNet::DnsBlockCallback
205/// A callback interface for GNet::DnsBlock.
206///
207 class GNet::DnsBlockCallback
208{
209 public:
210 virtual ~DnsBlockCallback() = default ;
211 ///< Desstructor.
212
213 virtual void onDnsBlockResult( const DnsBlockResult & ) = 0 ;
214 ///< Called with the results from DnsBlock::start().
215} ;
216
217// ==
218
219 inline
220 GNet::DnsBlockServerResult::DnsBlockServerResult( const std::string & server ) :
221 m_server(server) ,
222 m_valid(false)
223{
224}
225
226 inline
227 void GNet::DnsBlockServerResult::set( const std::vector<Address> & addresses )
228{
229 m_valid = true ;
230 m_addresses = addresses ;
231}
232
233 inline
234 bool GNet::DnsBlockServerResult::valid() const
235{
236 return m_valid ;
237}
238
239 inline
240std::string GNet::DnsBlockServerResult::server() const
241{
242 return m_server ;
243}
244
245 inline
246 const std::vector<GNet::Address> & GNet::DnsBlockServerResult::addresses() const
247{
248 return m_addresses ;
249}
250
251 inline
252 GNet::DnsBlockResult::DnsBlockResult() :
253 m_address(Address::defaultAddress())
254{
255}
256
257 inline
258 void GNet::DnsBlockResult::reset( std::size_t threshold , const Address & address )
259{
260 m_threshold = threshold ;
261 m_address = address ;
262}
263
264 inline
265GNet::DnsBlockResult::Type & GNet::DnsBlockResult::type()
266{
267 return m_type ;
268}
269
270 inline
271 const std::vector<GNet::DnsBlockServerResult> & GNet::DnsBlockResult::list() const
272{
273 return m_list ;
274}
275
276 inline
277 void GNet::DnsBlockResult::add( const DnsBlockServerResult & server_result )
278{
279 m_list.push_back( server_result ) ;
280}
281
282 inline
283 GNet::DnsBlockServerResult & GNet::DnsBlockResult::at( std::size_t i )
284{
285 return m_list.at( i ) ;
286}
287
288#endif
GNet::Address
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:53
GNet::DnsBlockCallback
A callback interface for GNet::DnsBlock.
Definition: gdnsblock.h:208
GNet::DnsBlockCallback::onDnsBlockResult
virtual void onDnsBlockResult(const DnsBlockResult &)=0
Called with the results from DnsBlock::start().
GNet::DnsBlockCallback::~DnsBlockCallback
virtual ~DnsBlockCallback()=default
Desstructor.
GNet::DnsBlockResult
A result structure for GNet::DnsBlock, as delivered by the DnsBlockCallback interface.
Definition: gdnsblock.h:78
GNet::DnsBlockResult::add
void add(const DnsBlockServerResult &)
Appends the server result.
Definition: gdnsblock.h:277
GNet::DnsBlockResult::warn
void warn() const
Emits warnings.
Definition: gdnsblock.cpp:283
GNet::DnsBlockResult::allow
bool allow() const
Returns true if the type is Inactive, Local, TimeoutAllow or Allow.
Definition: gdnsblock.cpp:299
GNet::DnsBlockResult::laggards
G::StringArray laggards() const
Returns the list of slow or unresponsive servers.
Definition: gdnsblock.cpp:327
GNet::DnsBlockResult::reset
void reset(std::size_t threshold, const Address &)
Initialiser.
Definition: gdnsblock.h:258
GNet::DnsBlockResult::type
Type & type()
Returns a settable reference to the overall result type.
Definition: gdnsblock.h:265
GNet::DnsBlockResult::at
DnsBlockServerResult & at(std::size_t)
Returns a reference to the given per-server result.
Definition: gdnsblock.h:283
GNet::DnsBlockResult::DnsBlockResult
DnsBlockResult()
Constructor.
Definition: gdnsblock.h:252
GNet::DnsBlockResult::list
const std::vector< DnsBlockServerResult > & list() const
Returns a reference to the per-server results.
Definition: gdnsblock.h:271
GNet::DnsBlockResult::deniers
G::StringArray deniers() const
Returns the list of denying servers.
Definition: gdnsblock.cpp:321
GNet::DnsBlockResult::log
void log() const
Logs the results.
Definition: gdnsblock.cpp:259
GNet::DnsBlockResult::deny
bool deny() const
Returns true if the type is TimeoutDeny or Deny.
Definition: gdnsblock.cpp:304
GNet::DnsBlockServerResult
A result structure for one DNSBL server.
Definition: gdnsblock.h:47
GNet::DnsBlockServerResult::valid
bool valid() const
Returns true if the list() is valid.
Definition: gdnsblock.h:234
GNet::DnsBlockServerResult::addresses
const std::vector< Address > & addresses() const
Returns the result list, which is empty if there is no block or not valid().
Definition: gdnsblock.h:246
GNet::DnsBlockServerResult::server
std::string server() const
Returns the server.
Definition: gdnsblock.h:240
GNet::DnsBlockServerResult::DnsBlockServerResult
DnsBlockServerResult(const std::string &server)
Constructor.
Definition: gdnsblock.h:220
GNet::DnsBlockServerResult::set
void set(const std::vector< Address > &)
Sets the result list().
Definition: gdnsblock.h:227
GNet::DnsBlock
Implements DNS blocklisting, as per RFC-5782.
Definition: gdnsblock.h:145
GNet::DnsBlock::checkConfig
static void checkConfig(const std::string &)
Checks the configure() string, throwing on error.
Definition: gdnsblock.cpp:101
GNet::DnsBlock::DnsBlock
DnsBlock(DnsBlockCallback &, ExceptionSink, const std::string &config=std::string())
Constructor.
Definition: gdnsblock.cpp:87
GNet::DnsBlock::configure
void configure(const Address &dns_server, std::size_t threshold, bool allow_on_timeout, G::TimeInterval timeout, const G::StringArray &servers)
Configures the object after construction.
Definition: gdnsblock.cpp:136
GNet::DnsBlock::start
void start(const Address &)
Starts an asychronous check on the given address.
Definition: gdnsblock.cpp:146
GNet::DnsBlock::busy
bool busy() const
Returns true after start() and before the completion callback.
Definition: gdnsblock.cpp:195
GNet::EventHandler
A base class for classes that handle asynchronous events from the event loop.
Definition: geventhandler.h:48
GNet::ExceptionSink
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
Definition: gexceptionsink.h:100
GNet::Local
A static class for getting information about the local machine's network name and address.
Definition: glocal.h:39
GNet::Timer
A timer class template in which the timeout is delivered to the specified method.
Definition: gtimer.h:129
G::TimeInterval
An interval between two G::SystemTime values or two G::TimerTime values.
Definition: gdatetime.h:289
gaddress.h
gdatetime.h
geventhandler.h
gexception.h
gexceptionsink.h
gsocket.h
gstrings.h
gtimer.h
GNet
Network classes.
Definition: gdef.h:1115
G::StringArray
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:31