Fabcoin Core  0.16.2
P2P Digital Currency
Common.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum 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  cpp-ethereum 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
22 #include "Common.h"
23 #include "Network.h"
24 using namespace std;
25 using namespace dev;
26 using namespace dev::p2p;
27 
28 const unsigned dev::p2p::c_protocolVersion = 4;
29 const unsigned dev::p2p::c_defaultIPPort = 30303;
30 static_assert(dev::p2p::c_protocolVersion == 4, "Replace v3 compatbility with v4 compatibility before updating network version.");
31 
34 
36 
37 //⊳⊲◀▶■▣▢□▷◁▧▨▩▲◆◉◈◇◎●◍◌○◼☑☒☎☢☣☰☀♽♥♠✩✭❓✔✓✖✕✘✓✔✅⚒⚡⦸⬌∅⁕«««»»»⚙━┅┉▬
38 
39 #if defined(_WIN32)
40 const char* NetWarn::name() { return EthYellow "N" EthRed " X"; }
41 const char* NetImpolite::name() { return EthYellow "N" EthRed " !"; }
42 const char* NetNote::name() { return EthYellow "N" EthBlue " i"; }
43 const char* NetConnect::name() { return EthYellow "N" EthYellow " C"; }
44 const char* NetMessageSummary::name() { return EthYellow "N" EthWhite " ."; }
45 const char* NetMessageDetail::name() { return EthYellow "N" EthGray " o"; }
46 const char* NetTriviaSummary::name() { return EthYellow "N" EthGray " O"; }
47 const char* NetTriviaDetail::name() { return EthYellow "N" EthCoal " 0"; }
48 const char* NetAllDetail::name() { return EthYellow "N" EthCoal " A"; }
49 const char* NetRight::name() { return EthYellow "N" EthGreen "->"; }
50 const char* NetLeft::name() { return EthYellow "N" EthNavy "<-"; }
51 const char* NetP2PWarn::name() { return EthYellow "N" EthRed " X"; }
52 const char* NetP2PNote::name() { return EthYellow "N" EthBlue " i"; }
53 const char* NetP2PConnect::name() { return EthYellow "N" EthYellow " C"; }
54 #else
55 const char* NetWarn::name() { return EthYellow "⧎" EthRed " ✘"; }
56 const char* NetImpolite::name() { return EthYellow "⧎" EthRed " !"; }
57 const char* NetNote::name() { return EthYellow "⧎" EthBlue " ℹ"; }
58 const char* NetConnect::name() { return EthYellow "⧎" EthYellow " ▢"; }
59 const char* NetMessageSummary::name() { return EthYellow "⧎" EthWhite " ◌"; }
60 const char* NetMessageDetail::name() { return EthYellow "⧎" EthGray " ○"; }
61 const char* NetTriviaSummary::name() { return EthYellow "⧎" EthGray " ◎"; }
62 const char* NetTriviaDetail::name() { return EthYellow "⧎" EthCoal " ◍"; }
63 const char* NetAllDetail::name() { return EthYellow "⧎" EthCoal " ●"; }
64 const char* NetRight::name() { return EthYellow "⧎" EthGreen "▬▶"; }
65 const char* NetLeft::name() { return EthYellow "⧎" EthNavy "◀▬"; }
66 const char* NetP2PWarn::name() { return EthYellow "⧎" EthRed " ✘"; }
67 const char* NetP2PNote::name() { return EthYellow "⧎" EthBlue " ℹ"; }
68 const char* NetP2PConnect::name() { return EthYellow "⧎" EthYellow " ▢"; }
69 #endif
70 
71 bool p2p::isPublicAddress(std::string const& _addressToCheck)
72 {
73  return _addressToCheck.empty() ? false : isPublicAddress(bi::address::from_string(_addressToCheck));
74 }
75 
76 bool p2p::isPublicAddress(bi::address const& _addressToCheck)
77 {
78  return !(isPrivateAddress(_addressToCheck) || isLocalHostAddress(_addressToCheck));
79 }
80 
81 // Helper function to determine if an address falls within one of the reserved ranges
82 // For V4:
83 // Class A "10.*", Class B "172.[16->31].*", Class C "192.168.*"
84 bool p2p::isPrivateAddress(bi::address const& _addressToCheck)
85 {
86  if (_addressToCheck.is_v4())
87  {
88  bi::address_v4 v4Address = _addressToCheck.to_v4();
89  bi::address_v4::bytes_type bytesToCheck = v4Address.to_bytes();
90  if (bytesToCheck[0] == 10 || bytesToCheck[0] == 127)
91  return true;
92  if (bytesToCheck[0] == 172 && (bytesToCheck[1] >= 16 && bytesToCheck[1] <= 31))
93  return true;
94  if (bytesToCheck[0] == 192 && bytesToCheck[1] == 168)
95  return true;
96  }
97  else if (_addressToCheck.is_v6())
98  {
99  bi::address_v6 v6Address = _addressToCheck.to_v6();
100  bi::address_v6::bytes_type bytesToCheck = v6Address.to_bytes();
101  if (bytesToCheck[0] == 0xfd && bytesToCheck[1] == 0)
102  return true;
103  if (!bytesToCheck[0] && !bytesToCheck[1] && !bytesToCheck[2] && !bytesToCheck[3] && !bytesToCheck[4] && !bytesToCheck[5] && !bytesToCheck[6] && !bytesToCheck[7]
104  && !bytesToCheck[8] && !bytesToCheck[9] && !bytesToCheck[10] && !bytesToCheck[11] && !bytesToCheck[12] && !bytesToCheck[13] && !bytesToCheck[14] && (bytesToCheck[15] == 0 || bytesToCheck[15] == 1))
105  return true;
106  }
107  return false;
108 }
109 
110 bool p2p::isPrivateAddress(std::string const& _addressToCheck)
111 {
112  return _addressToCheck.empty() ? false : isPrivateAddress(bi::address::from_string(_addressToCheck));
113 }
114 
115 // Helper function to determine if an address is localhost
116 bool p2p::isLocalHostAddress(bi::address const& _addressToCheck)
117 {
118  // @todo: ivp6 link-local adresses (macos), ex: fe80::1%lo0
119  static const set<bi::address> c_rejectAddresses = {
120  {bi::address_v4::from_string("127.0.0.1")},
121  {bi::address_v4::from_string("0.0.0.0")},
122  {bi::address_v6::from_string("::1")},
123  {bi::address_v6::from_string("::")}
124  };
125 
126  return find(c_rejectAddresses.begin(), c_rejectAddresses.end(), _addressToCheck) != c_rejectAddresses.end();
127 }
128 
129 bool p2p::isLocalHostAddress(std::string const& _addressToCheck)
130 {
131  return _addressToCheck.empty() ? false : isLocalHostAddress(bi::address::from_string(_addressToCheck));
132 }
133 
135 {
136  switch (_r)
137  {
138  case DisconnectRequested: return "Disconnect was requested.";
139  case TCPError: return "Low-level TCP communication error.";
140  case BadProtocol: return "Data format error.";
141  case UselessPeer: return "Peer had no use for this node.";
142  case TooManyPeers: return "Peer had too many connections.";
143  case DuplicatePeer: return "Peer was already connected.";
144  case IncompatibleProtocol: return "Peer protocol versions are incompatible.";
145  case NullIdentity: return "Null identity given.";
146  case ClientQuit: return "Peer is exiting.";
147  case UnexpectedIdentity: return "Unexpected identity given.";
148  case LocalIdentity: return "Connected to ourselves.";
149  case UserReason: return "Subprotocol reason.";
150  case NoDisconnect: return "(No disconnect has happened.)";
151  default: return "Unknown reason.";
152  }
153 }
154 
155 void NodeIPEndpoint::streamRLP(RLPStream& _s, RLPAppend _append) const
156 {
157  if (_append == StreamList)
158  _s.appendList(3);
159  if (address.is_v4())
160  _s << bytesConstRef(&address.to_v4().to_bytes()[0], 4);
161  else if (address.is_v6())
162  _s << bytesConstRef(&address.to_v6().to_bytes()[0], 16);
163  else
164  _s << bytes();
165  _s << udpPort << tcpPort;
166 }
167 
168 void NodeIPEndpoint::interpretRLP(RLP const& _r)
169 {
170  if (_r[0].size() == 4)
171  address = bi::address_v4(*(bi::address_v4::bytes_type*)_r[0].toBytes().data());
172  else if (_r[0].size() == 16)
173  address = bi::address_v6(*(bi::address_v6::bytes_type*)_r[0].toBytes().data());
174  else
175  address = bi::address();
176  udpPort = _r[1].toInt<uint16_t>();
177  tcpPort = _r[2].toInt<uint16_t>();
178 }
179 
180 void DeadlineOps::reap()
181 {
182  if (m_stopped)
183  return;
184 
185  Guard l(x_timers);
186  std::vector<DeadlineOp>::iterator t = m_timers.begin();
187  while (t != m_timers.end())
188  if (t->expired())
189  {
190  t->wait();
191  t = m_timers.erase(t);
192  }
193  else
194  t++;
195 
196  m_timers.emplace_back(m_io, m_reapIntervalMs, [this](boost::system::error_code const& ec)
197  {
198  if (!ec && !m_stopped)
199  reap();
200  });
201 }
202 
203 Node::Node(NodeSpec const& _s, PeerType _p):
204  id(_s.id()),
205  endpoint(_s.nodeIPEndpoint()),
206  peerType(_p)
207 {}
208 
209 NodeSpec::NodeSpec(string const& _user)
210 {
211  m_address = _user;
212  if (m_address.substr(0, 8) == "enode://" && m_address.find('@') == 136)
213  {
214  m_id = p2p::NodeID(m_address.substr(8, 128));
215  m_address = m_address.substr(137);
216  }
217  size_t colon = m_address.find_first_of(":");
218  if (colon != string::npos)
219  {
220  string ports = m_address.substr(colon + 1);
221  m_address = m_address.substr(0, colon);
222  size_t p2 = ports.find_first_of(".");
223  if (p2 != string::npos)
224  {
225  m_udpPort = stoi(ports.substr(p2 + 1));
226  m_tcpPort = stoi(ports.substr(0, p2));
227  }
228  else
229  m_tcpPort = m_udpPort = stoi(ports);
230  }
231 }
232 
234 {
235  return NodeIPEndpoint(p2p::Network::resolveHost(m_address).address(), m_udpPort, m_tcpPort);
236 }
237 
238 std::string NodeSpec::enode() const
239 {
240  string ret = m_address;
241 
242  if (m_tcpPort)
243  if (m_udpPort && m_tcpPort != m_udpPort)
244  ret += ":" + toString(m_tcpPort) + "." + toString(m_udpPort);
245  else
246  ret += ":" + toString(m_tcpPort);
247  else if (m_udpPort)
248  ret += ":" + toString(m_udpPort);
249 
250  if (m_id)
251  return "enode://" + m_id.hex() + "@" + ret;
252  return ret;
253 }
254 
255 namespace dev
256 {
257 
258 std::ostream& operator<<(std::ostream& _out, dev::p2p::NodeIPEndpoint const& _ep)
259 {
260  _out << _ep.address << _ep.udpPort << _ep.tcpPort;
261  return _out;
262 }
263 
264 }
265 
h512 NodeID
Definition: Common.h:62
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
bi::address address
Definition: Common.h:209
bool isPrivateAddress(bi::address const &_addressToCheck)
Definition: Common.cpp:84
bool isLocalHostAddress(bi::address const &_addressToCheck)
Definition: Common.cpp:116
bool isPublicAddress(bi::address const &_addressToCheck)
Definition: Common.cpp:76
#define EthGreen
Definition: Terminal.h:122
std::hash for asio::adress
Definition: Common.h:323
const unsigned c_protocolVersion
Peer network protocol version.
Definition: Common.cpp:28
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
Definition: CommonData.cpp:141
IPv4,UDP/TCP endpoints.
Definition: Common.h:175
DisconnectReason
Definition: Common.h:106
std::string reasonOf(DisconnectReason _r)
Definition: Common.cpp:134
std::lock_guard< std::mutex > Guard
Definition: Guards.h:41
const char * name
Definition: rest.cpp:36
#define EthWhite
Definition: Terminal.h:119
std::vector< byte > bytes
Definition: Common.h:75
const Node UnspecifiedNode
Definition: Common.cpp:33
vector_ref< byte const > bytesConstRef
Definition: Common.h:77
RLPStream & appendList(size_t _items)
Appends a list.
Definition: RLP.cpp:276
#define EthGray
Definition: Terminal.h:118
NodeIPEndpoint nodeIPEndpoint() const
Definition: Common.cpp:233
static bi::tcp::endpoint resolveHost(std::string const &_host)
Resolve "host:port" string as TCP endpoint. Returns unspecified endpoint on failure.
Definition: Network.cpp:216
#define EthNavy
Definition: Terminal.h:126
virtual NodeID const & address() const
Definition: Common.h:248
uint8_t const size_t const size
Definition: sha3.h:20
PeerType
Definition: Common.h:166
const unsigned c_defaultIPPort
Definition: Common.cpp:29
#define EthCoal
Definition: Terminal.h:117
std::string enode() const
Definition: Common.cpp:238
struct evm_uint160be address(struct evm_env *env)
Definition: capi.c:13
#define EthYellow
Definition: Terminal.h:125
#define EthBlue
Definition: Terminal.h:127
#define EthRed
Definition: Terminal.h:121
std::ostream & operator<<(std::ostream &_out, NodeTable const &_nodeTable)
Definition: NodeTable.h:270
_T toInt(int _flags=Strict) const
Converts to int of type given; if isString(), decodes as big-endian bytestream.
Definition: RLP.h:275
Class for writing to an RLP bytestream.
Definition: RLP.h:383
const NodeIPEndpoint UnspecifiedNodeIPEndpoint
Definition: Common.cpp:32
uint8_t const * data
Definition: sha3.h:19
Class for interpreting Recursive Linear-Prefix Data.
Definition: RLP.h:64
static bool test_allowLocal
Setting true causes isAllowed to return true for all addresses. (Used by test fixtures) ...
Definition: Common.h:185