Monero
net_peerlist_boost_serialization.h
Go to the documentation of this file.
1 // Copyright (c) 2014-2020, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29 // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
30 
31 #pragma once
32 
33 #include <cstring>
34 
35 #include "common/expect.h"
36 #include "net/net_utils_base.h"
37 #include "net/tor_address.h"
38 #include "net/i2p_address.h"
39 #include "p2p/p2p_protocol_defs.h"
40 
41 #ifdef CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED
42 #include "common/pruning.h"
43 #endif
44 
46 
47 namespace boost
48 {
49  namespace serialization
50  {
51  template <class T, class Archive>
52  inline void do_serialize(boost::mpl::false_, Archive &a, epee::net_utils::network_address& na)
53  {
54  T addr{};
55  a & addr;
56  na = std::move(addr);
57  }
58 
59  template <class T, class Archive>
60  inline void do_serialize(boost::mpl::true_, Archive &a, const epee::net_utils::network_address& na)
61  {
62  a & na.as<T>();
63  }
64 
65  template <class Archive, class ver_type>
66  inline void serialize(Archive &a, epee::net_utils::network_address& na, const ver_type ver)
67  {
68  static constexpr const typename Archive::is_saving is_saving{};
69 
70  uint8_t type;
71  if (is_saving)
72  type = uint8_t(na.get_type_id());
73  a & type;
74  switch (epee::net_utils::address_type(type))
75  {
76  case epee::net_utils::ipv4_network_address::get_type_id():
77  do_serialize<epee::net_utils::ipv4_network_address>(is_saving, a, na);
78  break;
79  case epee::net_utils::ipv6_network_address::get_type_id():
80  do_serialize<epee::net_utils::ipv6_network_address>(is_saving, a, na);
81  break;
83  do_serialize<net::tor_address>(is_saving, a, na);
84  break;
86  do_serialize<net::i2p_address>(is_saving, a, na);
87  break;
88  case epee::net_utils::address_type::invalid:
89  default:
90  throw std::runtime_error("Unsupported network address type");
91  }
92  }
93  template <class Archive, class ver_type>
94  inline void serialize(Archive &a, epee::net_utils::ipv4_network_address& na, const ver_type ver)
95  {
96  uint32_t ip{na.ip()};
97  uint16_t port{na.port()};
98  ip = SWAP32LE(ip);
99  a & ip;
100  ip = SWAP32LE(ip);
101  a & port;
102  if (!typename Archive::is_saving())
103  na = epee::net_utils::ipv4_network_address{ip, port};
104  }
105 
106  template <class Archive, class ver_type>
107  inline void serialize(Archive &a, boost::asio::ip::address_v6& v6, const ver_type ver)
108  {
109  if (typename Archive::is_saving())
110  {
111  auto bytes = v6.to_bytes();
112  for (auto &e: bytes) a & e;
113  }
114  else
115  {
116  boost::asio::ip::address_v6::bytes_type bytes;
117  for (auto &e: bytes) a & e;
118  v6 = boost::asio::ip::address_v6(bytes);
119  }
120  }
121 
122  template <class Archive, class ver_type>
123  inline void serialize(Archive &a, epee::net_utils::ipv6_network_address& na, const ver_type ver)
124  {
125  boost::asio::ip::address_v6 ip{na.ip()};
126  uint16_t port{na.port()};
127  a & ip;
128  a & port;
129  if (!typename Archive::is_saving())
130  na = epee::net_utils::ipv6_network_address{ip, port};
131  }
132 
133 
134  template <class Archive, class ver_type>
135  inline void save(Archive& a, const net::tor_address& na, const ver_type)
136  {
137  const size_t length = std::strlen(na.host_str());
138  if (length > 255)
139  MONERO_THROW(net::error::invalid_tor_address, "Tor address too long");
140 
141  const uint16_t port{na.port()};
142  const uint8_t len = length;
143  a & port;
144  a & len;
145  a.save_binary(na.host_str(), length);
146  }
147 
148  template <class Archive, class ver_type>
149  inline void save(Archive& a, const net::i2p_address& na, const ver_type)
150  {
151  const size_t length = std::strlen(na.host_str());
152  if (length > 255)
153  MONERO_THROW(net::error::invalid_i2p_address, "i2p address too long");
154 
155  const uint16_t port{na.port()};
156  const uint8_t len = length;
157  a & port;
158  a & len;
159  a.save_binary(na.host_str(), length);
160  }
161 
162  template <class Archive, class ver_type>
163  inline void load(Archive& a, net::tor_address& na, const ver_type)
164  {
165  uint16_t port = 0;
166  uint8_t length = 0;
167  a & port;
168  a & length;
169 
170  const size_t buffer_size = net::tor_address::buffer_size();
171  if (length > buffer_size)
172  MONERO_THROW(net::error::invalid_tor_address, "Tor address too long");
173 
174  char host[buffer_size] = {0};
175  a.load_binary(host, length);
176  host[sizeof(host) - 1] = 0;
177 
178  if (std::strcmp(host, net::tor_address::unknown_str()) == 0)
180  else
181  na = MONERO_UNWRAP(net::tor_address::make(host, port));
182  }
183 
184  template <class Archive, class ver_type>
185  inline void load(Archive& a, net::i2p_address& na, const ver_type)
186  {
187  uint16_t port = 0;
188  uint8_t length = 0;
189  a & port;
190  a & length;
191 
192  const size_t buffer_size = net::i2p_address::buffer_size();
193  if (length > buffer_size)
194  MONERO_THROW(net::error::invalid_i2p_address, "i2p address too long");
195 
196  char host[buffer_size] = {0};
197  a.load_binary(host, length);
198  host[sizeof(host) - 1] = 0;
199 
200  if (std::strcmp(host, net::i2p_address::unknown_str()) == 0)
202  else
203  na = MONERO_UNWRAP(net::i2p_address::make(host, port));
204  }
205 
206  template <class Archive, class ver_type>
207  inline void serialize(Archive &a, net::tor_address& na, const ver_type ver)
208  {
209  boost::serialization::split_free(a, na, ver);
210  }
211 
212  template <class Archive, class ver_type>
213  inline void serialize(Archive &a, net::i2p_address& na, const ver_type ver)
214  {
215  boost::serialization::split_free(a, na, ver);
216  }
217 
218  template <class Archive, class ver_type>
219  inline void serialize(Archive &a, nodetool::peerlist_entry& pl, const ver_type ver)
220  {
221  a & pl.adr;
222  a & pl.id;
223  a & pl.last_seen;
224  if (ver < 1)
225  {
226  if (!typename Archive::is_saving())
227  pl.pruning_seed = 0;
228  return;
229  }
230  a & pl.pruning_seed;
231 #ifdef CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED
232  if (!typename Archive::is_saving())
233  {
234  pl.pruning_seed = tools::make_pruning_seed(1+pl.adr.as<epee::net_utils::ipv4_network_address>().ip() % (1<<CRYPTONOTE_PRUNING_LOG_STRIPES), CRYPTONOTE_PRUNING_LOG_STRIPES);
235  }
236 #endif
237  if (ver < 2)
238  {
239  if (!typename Archive::is_saving())
240  pl.rpc_port = 0;
241  return;
242  }
243  a & pl.rpc_port;
244  if (ver < 3)
245  {
246  if (!typename Archive::is_saving())
247  pl.rpc_credits_per_hash = 0;
248  return;
249  }
250  a & pl.rpc_credits_per_hash;
251  }
252 
253  template <class Archive, class ver_type>
254  inline void serialize(Archive &a, nodetool::anchor_peerlist_entry& pl, const ver_type ver)
255  {
256  a & pl.adr;
257  a & pl.id;
258  a & pl.first_seen;
259  }
260  }
261 }
b32 i2p address; internal format not condensed/decoded.
Definition: i2p_address.h:52
std::uint16_t port() const noexcept
Definition: i2p_address.h:107
static i2p_address unknown() noexcept
Definition: i2p_address.h:70
static constexpr epee::net_utils::address_type get_type_id() noexcept
Definition: i2p_address.h:112
static constexpr std::size_t buffer_size() noexcept
Definition: i2p_address.h:61
static expect< i2p_address > make(boost::string_ref address, std::uint16_t default_port=0)
Definition: i2p_address.cpp:107
const char * host_str() const noexcept
Definition: i2p_address.h:104
static const char * unknown_str() noexcept
Definition: i2p_address.cpp:94
Tor onion address; internal format not condensed/decoded.
Definition: tor_address.h:52
static expect< tor_address > make(boost::string_ref address, std::uint16_t default_port=0)
Definition: tor_address.cpp:108
static constexpr std::size_t buffer_size() noexcept
Definition: tor_address.h:61
static const char * unknown_str() noexcept
Definition: tor_address.cpp:95
static constexpr epee::net_utils::address_type get_type_id() noexcept
Definition: tor_address.h:112
std::uint16_t port() const noexcept
Definition: tor_address.h:107
static tor_address unknown() noexcept
Definition: tor_address.h:70
const char * host_str() const noexcept
Definition: tor_address.h:104
#define CRYPTONOTE_PRUNING_LOG_STRIPES
Definition: cryptonote_config.h:195
#define MONERO_THROW(code, msg)
Definition: expect.h:66
#define MONERO_UNWRAP(...)
Definition: expect.h:60
const uint32_t T[512]
Definition: groestl_tables.h:36
string a
Definition: MakeCryptoOps.py:15
void load(Archive &a, net::i2p_address &na, const ver_type)
Definition: net_peerlist_boost_serialization.h:185
void do_serialize(boost::mpl::true_, Archive &a, const epee::net_utils::network_address &na)
Definition: net_peerlist_boost_serialization.h:60
void save(Archive &a, const net::i2p_address &na, const ver_type)
Definition: net_peerlist_boost_serialization.h:149
Definition: unordered_containers_boost_serialization.h:38
@ invalid_tor_address
Invalid base32 or length.
@ invalid_i2p_address
Definition: binary_utils.h:36
bool serialize(Archive &ar, T &v)
Definition: serialization.h:382
uint32_t make_pruning_seed(uint32_t stripe, uint32_t log_stripes)
Definition: pruning.cpp:37
BOOST_CLASS_VERSION(nodetool::peerlist_types, nodetool::CURRENT_PEERLIST_STORAGE_ARCHIVE_VER)
Definition: p2p_protocol_defs.h:102
int64_t first_seen
Definition: p2p_protocol_defs.h:105
AddressType adr
Definition: p2p_protocol_defs.h:103
peerid_type id
Definition: p2p_protocol_defs.h:104
Definition: p2p_protocol_defs.h:72
uint32_t pruning_seed
Definition: p2p_protocol_defs.h:76
AddressType adr
Definition: p2p_protocol_defs.h:73
uint16_t rpc_port
Definition: p2p_protocol_defs.h:77
peerid_type id
Definition: p2p_protocol_defs.h:74
int64_t last_seen
Definition: p2p_protocol_defs.h:75
uint32_t rpc_credits_per_hash
Definition: p2p_protocol_defs.h:78