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
35namespace 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///
47{
48public:
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
65private:
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///
78{
79public:
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
90public:
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
127private:
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///
145{
146public:
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
173public:
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
180private: // overrides
181 void readEvent() override ; // Override from GNet::EventHandler.
182
183private:
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
190private:
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///
208{
209public:
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
219inline
221 m_server(server) ,
222 m_valid(false)
223{
224}
225
226inline
227void GNet::DnsBlockServerResult::set( const std::vector<Address> & addresses )
228{
229 m_valid = true ;
230 m_addresses = addresses ;
231}
232
233inline
235{
236 return m_valid ;
237}
238
239inline
241{
242 return m_server ;
243}
244
245inline
246const std::vector<GNet::Address> & GNet::DnsBlockServerResult::addresses() const
247{
248 return m_addresses ;
249}
250
251inline
253 m_address(Address::defaultAddress())
254{
255}
256
257inline
258void GNet::DnsBlockResult::reset( std::size_t threshold , const Address & address )
259{
260 m_threshold = threshold ;
261 m_address = address ;
262}
263
264inline
265GNet::DnsBlockResult::Type & GNet::DnsBlockResult::type()
266{
267 return m_type ;
268}
269
270inline
271const std::vector<GNet::DnsBlockServerResult> & GNet::DnsBlockResult::list() const
272{
273 return m_list ;
274}
275
276inline
278{
279 m_list.push_back( server_result ) ;
280}
281
282inline
284{
285 return m_list.at( i ) ;
286}
287
288#endif
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:53
A callback interface for GNet::DnsBlock.
Definition: gdnsblock.h:208
virtual void onDnsBlockResult(const DnsBlockResult &)=0
Called with the results from DnsBlock::start().
virtual ~DnsBlockCallback()=default
Desstructor.
A result structure for GNet::DnsBlock, as delivered by the DnsBlockCallback interface.
Definition: gdnsblock.h:78
void add(const DnsBlockServerResult &)
Appends the server result.
Definition: gdnsblock.h:277
void warn() const
Emits warnings.
Definition: gdnsblock.cpp:283
bool allow() const
Returns true if the type is Inactive, Local, TimeoutAllow or Allow.
Definition: gdnsblock.cpp:299
G::StringArray laggards() const
Returns the list of slow or unresponsive servers.
Definition: gdnsblock.cpp:327
void reset(std::size_t threshold, const Address &)
Initialiser.
Definition: gdnsblock.h:258
Type & type()
Returns a settable reference to the overall result type.
Definition: gdnsblock.h:265
DnsBlockServerResult & at(std::size_t)
Returns a reference to the given per-server result.
Definition: gdnsblock.h:283
DnsBlockResult()
Constructor.
Definition: gdnsblock.h:252
const std::vector< DnsBlockServerResult > & list() const
Returns a reference to the per-server results.
Definition: gdnsblock.h:271
G::StringArray deniers() const
Returns the list of denying servers.
Definition: gdnsblock.cpp:321
void log() const
Logs the results.
Definition: gdnsblock.cpp:259
bool deny() const
Returns true if the type is TimeoutDeny or Deny.
Definition: gdnsblock.cpp:304
A result structure for one DNSBL server.
Definition: gdnsblock.h:47
bool valid() const
Returns true if the list() is valid.
Definition: gdnsblock.h:234
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
std::string server() const
Returns the server.
Definition: gdnsblock.h:240
DnsBlockServerResult(const std::string &server)
Constructor.
Definition: gdnsblock.h:220
void set(const std::vector< Address > &)
Sets the result list().
Definition: gdnsblock.h:227
Implements DNS blocklisting, as per RFC-5782.
Definition: gdnsblock.h:145
static void checkConfig(const std::string &)
Checks the configure() string, throwing on error.
Definition: gdnsblock.cpp:101
DnsBlock(DnsBlockCallback &, ExceptionSink, const std::string &config=std::string())
Constructor.
Definition: gdnsblock.cpp:87
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
void start(const Address &)
Starts an asychronous check on the given address.
Definition: gdnsblock.cpp:146
bool busy() const
Returns true after start() and before the completion callback.
Definition: gdnsblock.cpp:195
A base class for classes that handle asynchronous events from the event loop.
Definition: geventhandler.h:48
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
A static class for getting information about the local machine's network name and address.
Definition: glocal.h:39
A timer class template in which the timeout is delivered to the specified method.
Definition: gtimer.h:129
An interval between two G::SystemTime values or two G::TimerTime values.
Definition: gdatetime.h:289
Network classes.
Definition: gdef.h:1115
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:31