Electroneum
Loading...
Searching...
No Matches
net_utils_base.h
Go to the documentation of this file.
1// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above copyright
9// notice, this list of conditions and the following disclaimer in the
10// documentation and/or other materials provided with the distribution.
11// * Neither the name of the Andrey N. Sabelnikov nor the
12// names of its contributors may be used to endorse or promote products
13// derived from this software without specific prior written permission.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
19// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25//
26
27
28
29#ifndef _NET_UTILS_BASE_H_
30#define _NET_UTILS_BASE_H_
31
32#include <boost/uuid/uuid.hpp>
33#include <boost/asio/io_service.hpp>
34#include <typeinfo>
35#include <type_traits>
36#include "enums.h"
38#include "misc_log_ex.h"
39
40#undef ELECTRONEUM_DEFAULT_LOG_CATEGORY
41#define ELECTRONEUM_DEFAULT_LOG_CATEGORY "net"
42
43#ifndef MAKE_IP
44#define MAKE_IP( a1, a2, a3, a4 ) (a1|(a2<<8)|(a3<<16)|(a4<<24))
45#endif
46
47#if BOOST_VERSION >= 107000
48#define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context())
49#else
50#define GET_IO_SERVICE(s) ((s).get_io_service())
51#endif
52
53namespace net
54{
55 class tor_address;
56 class i2p_address;
57}
58
59namespace epee
60{
61namespace net_utils
62{
64 {
65 uint32_t m_ip;
66 uint16_t m_port;
67
68 public:
69 constexpr ipv4_network_address() noexcept
71 {}
72
74 : m_ip(ip), m_port(port) {}
75
76 bool equal(const ipv4_network_address& other) const noexcept;
77 bool less(const ipv4_network_address& other) const noexcept;
78 constexpr bool is_same_host(const ipv4_network_address& other) const noexcept
79 { return ip() == other.ip(); }
80
81 constexpr uint32_t ip() const noexcept { return m_ip; }
82 constexpr uint16_t port() const noexcept { return m_port; }
83 std::string str() const;
84 std::string host_str() const;
85 bool is_loopback() const;
86 bool is_local() const;
87 static constexpr address_type get_type_id() noexcept { return address_type::ipv4; }
88 static constexpr zone get_zone() noexcept { return zone::public_; }
89 static constexpr bool is_blockable() noexcept { return true; }
90
92 KV_SERIALIZE(m_ip)
95 };
96
97 inline bool operator==(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept
98 { return lhs.equal(rhs); }
99 inline bool operator!=(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept
100 { return !lhs.equal(rhs); }
101 inline bool operator<(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept
102 { return lhs.less(rhs); }
103 inline bool operator<=(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept
104 { return !rhs.less(lhs); }
105 inline bool operator>(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept
106 { return rhs.less(lhs); }
107 inline bool operator>=(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept
108 { return !lhs.less(rhs); }
109
111 {
112 struct interface
113 {
114 virtual ~interface() {};
115
116 virtual bool equal(const interface&) const = 0;
117 virtual bool less(const interface&) const = 0;
118 virtual bool is_same_host(const interface&) const = 0;
119
120 virtual std::string str() const = 0;
121 virtual std::string host_str() const = 0;
122 virtual bool is_loopback() const = 0;
123 virtual bool is_local() const = 0;
124 virtual address_type get_type_id() const = 0;
125 virtual zone get_zone() const = 0;
126 virtual bool is_blockable() const = 0;
127 };
128
129 template<typename T>
130 struct implementation final : interface
131 {
132 T value;
133
134 implementation(const T& src) : value(src) {}
135 ~implementation() = default;
136
137 // Type-checks for cast are done in cpp
138 static const T& cast(const interface& src) noexcept
139 { return static_cast<const implementation<T>&>(src).value; }
140
141 virtual bool equal(const interface& other) const override
142 { return value.equal(cast(other)); }
143
144 virtual bool less(const interface& other) const override
145 { return value.less(cast(other)); }
146
147 virtual bool is_same_host(const interface& other) const override
148 { return value.is_same_host(cast(other)); }
149
150 virtual std::string str() const override { return value.str(); }
151 virtual std::string host_str() const override { return value.host_str(); }
152 virtual bool is_loopback() const override { return value.is_loopback(); }
153 virtual bool is_local() const override { return value.is_local(); }
154 virtual address_type get_type_id() const override { return value.get_type_id(); }
155 virtual zone get_zone() const override { return value.get_zone(); }
156 virtual bool is_blockable() const override { return value.is_blockable(); }
157 };
158
159 std::shared_ptr<interface> self;
160
161 template<typename Type>
162 Type& as_mutable() const
163 {
164 // types `implmentation<Type>` and `implementation<const Type>` are unique
165 using Type_ = typename std::remove_const<Type>::type;
166 network_address::interface* const self_ = self.get(); // avoid clang warning in typeid
167 if (!self_ || typeid(implementation<Type_>) != typeid(*self_))
168 throw std::bad_cast{};
169 return static_cast<implementation<Type_>*>(self_)->value;
170 }
171
172 template<typename T, typename t_storage>
173 bool serialize_addr(std::false_type, t_storage& stg, typename t_storage::hsection hparent)
174 {
175 T addr{};
176 if (!epee::serialization::selector<false>::serialize(addr, stg, hparent, "addr"))
177 return false;
178 *this = std::move(addr);
179 return true;
180 }
181
182 template<typename T, typename t_storage>
183 bool serialize_addr(std::true_type, t_storage& stg, typename t_storage::hsection hparent) const
184 {
185 return epee::serialization::selector<true>::serialize(as<T>(), stg, hparent, "addr");
186 }
187
188 public:
189 network_address() : self(nullptr) {}
190 template<typename T>
191 network_address(const T& src)
192 : self(std::make_shared<implementation<T>>(src)) {}
193 bool equal(const network_address &other) const;
194 bool less(const network_address &other) const;
195 bool is_same_host(const network_address &other) const;
196 std::string str() const { return self ? self->str() : "<none>"; }
197 std::string host_str() const { return self ? self->host_str() : "<none>"; }
198 bool is_loopback() const { return self ? self->is_loopback() : false; }
199 bool is_local() const { return self ? self->is_local() : false; }
200 address_type get_type_id() const { return self ? self->get_type_id() : address_type::invalid; }
201 zone get_zone() const { return self ? self->get_zone() : zone::public_; }
202 bool is_blockable() const { return self ? self->is_blockable() : false; }
203 template<typename Type> const Type &as() const { return as_mutable<const Type>(); }
204
206 // need to `#include "net/[i2p|tor]_address.h"` when serializing `network_address`
207 static constexpr std::integral_constant<bool, is_store> is_store_{};
208
209 std::uint8_t type = std::uint8_t(is_store ? this_ref.get_type_id() : address_type::invalid);
210 if (!epee::serialization::selector<is_store>::serialize(type, stg, hparent_section, "type"))
211 return false;
212
214 {
216 return this_ref.template serialize_addr<ipv4_network_address>(is_store_, stg, hparent_section);
218 return this_ref.template serialize_addr<net::tor_address>(is_store_, stg, hparent_section);
220 return this_ref.template serialize_addr<net::i2p_address>(is_store_, stg, hparent_section);
222 default:
223 break;
224 }
225
226 MERROR("Unsupported network address type: " << (unsigned)type);
227 return false;
229 };
230
231 inline bool operator==(const network_address& lhs, const network_address& rhs)
232 { return lhs.equal(rhs); }
233 inline bool operator!=(const network_address& lhs, const network_address& rhs)
234 { return !lhs.equal(rhs); }
235 inline bool operator<(const network_address& lhs, const network_address& rhs)
236 { return lhs.less(rhs); }
237 inline bool operator<=(const network_address& lhs, const network_address& rhs)
238 { return !rhs.less(lhs); }
239 inline bool operator>(const network_address& lhs, const network_address& rhs)
240 { return rhs.less(lhs); }
241 inline bool operator>=(const network_address& lhs, const network_address& rhs)
242 { return !lhs.less(rhs); }
243
244 /************************************************************************/
245 /* */
246 /************************************************************************/
248 {
249 const boost::uuids::uuid m_connection_id;
251 const bool m_is_income;
252 const time_t m_started;
253 const time_t m_ssl;
262
263 connection_context_base(boost::uuids::uuid connection_id,
264 const network_address &remote_address, bool is_income, bool ssl,
265 time_t last_recv = 0, time_t last_send = 0,
266 uint64_t recv_cnt = 0, uint64_t send_cnt = 0):
267 m_connection_id(connection_id),
268 m_remote_address(remote_address),
269 m_is_income(is_income),
270 m_started(time(NULL)),
271 m_ssl(ssl),
272 m_last_recv(last_recv),
273 m_last_send(last_send),
274 m_recv_cnt(recv_cnt),
275 m_send_cnt(send_cnt),
280 {}
281
296
298 {
299 set_details(a.m_connection_id, a.m_remote_address, a.m_is_income, a.m_ssl);
300 }
301
303 {
304 set_details(a.m_connection_id, a.m_remote_address, a.m_is_income, a.m_ssl);
305 return *this;
306 }
307
308 private:
309 template<class t_protocol_handler>
310 friend class connection;
311 void set_details(boost::uuids::uuid connection_id, const network_address &remote_address, bool is_income, bool ssl)
312 {
314 new(this) connection_context_base(connection_id, remote_address, is_income, ssl);
315 }
316
317 };
318
319 /************************************************************************/
320 /* */
321 /************************************************************************/
323 {
324 virtual bool do_send(const void* ptr, size_t cb)=0;
325 virtual bool close()=0;
326 virtual bool send_done()=0;
327 virtual bool call_run_once_service_io()=0;
328 virtual bool request_callback()=0;
329 virtual boost::asio::io_service& get_io_service()=0;
330 //protect from deletion connection object(with protocol instance) during external call "invoke"
331 virtual bool add_ref()=0;
332 virtual bool release()=0;
333 protected:
334 virtual ~i_service_endpoint() noexcept(false) {}
335 };
336
337
338 //some helpers
339
340
341 std::string print_connection_context(const connection_context_base& ctx);
342 std::string print_connection_context_short(const connection_context_base& ctx);
343
345{
347 return os;
348}
349
350#define LOG_ERROR_CC(ct, message) MERROR(ct << message)
351#define LOG_WARNING_CC(ct, message) MWARNING(ct << message)
352#define LOG_INFO_CC(ct, message) MINFO(ct << message)
353#define LOG_DEBUG_CC(ct, message) MDEBUG(ct << message)
354#define LOG_TRACE_CC(ct, message) MTRACE(ct << message)
355#define LOG_CC(level, ct, message) MLOG(level, ct << message)
356
357#define LOG_PRINT_CC_L0(ct, message) LOG_PRINT_L0(ct << message)
358#define LOG_PRINT_CC_L1(ct, message) LOG_PRINT_L1(ct << message)
359#define LOG_PRINT_CC_L2(ct, message) LOG_PRINT_L2(ct << message)
360#define LOG_PRINT_CC_L3(ct, message) LOG_PRINT_L3(ct << message)
361#define LOG_PRINT_CC_L4(ct, message) LOG_PRINT_L4(ct << message)
362
363#define LOG_PRINT_CCONTEXT_L0(message) LOG_PRINT_CC_L0(context, message)
364#define LOG_PRINT_CCONTEXT_L1(message) LOG_PRINT_CC_L1(context, message)
365#define LOG_PRINT_CCONTEXT_L2(message) LOG_PRINT_CC_L2(context, message)
366#define LOG_PRINT_CCONTEXT_L3(message) LOG_PRINT_CC_L3(context, message)
367#define LOG_ERROR_CCONTEXT(message) LOG_ERROR_CC(context, message)
368
369#define CHECK_AND_ASSERT_MES_CC(condition, return_val, err_message) CHECK_AND_ASSERT_MES(condition, return_val, "[" << epee::net_utils::print_connection_context_short(context) << "]" << err_message)
370
371}
372}
373
374#endif //_NET_UTILS_BASE_H_
time_t time
static constexpr zone get_zone() noexcept
constexpr bool is_same_host(const ipv4_network_address &other) const noexcept
bool less(const ipv4_network_address &other) const noexcept
static constexpr address_type get_type_id() noexcept
static constexpr bool is_blockable() noexcept
constexpr uint16_t port() const noexcept
constexpr uint32_t ip() const noexcept
bool equal(const ipv4_network_address &other) const noexcept
constexpr ipv4_network_address(uint32_t ip, uint16_t port) noexcept
constexpr ipv4_network_address() noexcept
bool equal(const network_address &other) const
MERROR("Unsupported network address type: "<<(unsigned) type)
bool less(const network_address &other) const
bool is_same_host(const network_address &other) const
static constexpr std::integral_constant< bool, is_store > is_store_
b32 i2p address; internal format not condensed/decoded.
Definition i2p_address.h:52
Tor onion address; internal format not condensed/decoded.
Definition tor_address.h:52
#define MAKE_LOGGABLE(ClassType, ClassInstance, OutputStreamInstance)
#define inline
Definition inline_c.h:35
#define KV_SERIALIZE(varialble)
#define END_KV_SERIALIZE_MAP()
#define BEGIN_KV_SERIALIZE_MAP()
bool operator<=(const ipv4_network_address &lhs, const ipv4_network_address &rhs) noexcept
bool operator==(const ipv4_network_address &lhs, const ipv4_network_address &rhs) noexcept
std::string print_connection_context_short(const connection_context_base &ctx)
std::string print_connection_context(const connection_context_base &ctx)
bool operator!=(const ipv4_network_address &lhs, const ipv4_network_address &rhs) noexcept
bool operator>=(const ipv4_network_address &lhs, const ipv4_network_address &rhs) noexcept
bool operator>(const ipv4_network_address &lhs, const ipv4_network_address &rhs) noexcept
bool operator<(const ipv4_network_address &lhs, const ipv4_network_address &rhs) noexcept
STL namespace.
const GenericPointer< typename T::ValueType > T2 value
Definition pointer.h:1225
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1124
Type
Type of JSON value.
Definition rapidjson.h:620
#define false
unsigned short uint16_t
Definition stdint.h:125
unsigned int uint32_t
Definition stdint.h:126
unsigned __int64 uint64_t
Definition stdint.h:136
connection_context_base(boost::uuids::uuid connection_id, const network_address &remote_address, bool is_income, bool ssl, time_t last_recv=0, time_t last_send=0, uint64_t recv_cnt=0, uint64_t send_cnt=0)
connection_context_base(const connection_context_base &a)
connection_context_base & operator=(const connection_context_base &a)
virtual ~i_service_endpoint() noexcept(false)
virtual bool call_run_once_service_io()=0
virtual boost::asio::io_service & get_io_service()=0
virtual bool do_send(const void *ptr, size_t cb)=0
#define T(x)