Browse Source

Populate the peer address and port appropriately during the session creation time.

In addition, this patch will check both outgoing and incoming peers to determine
if they are in the V4 private address range and skip them.
Peer sessions that do not set a listen port are not propagated via the GetPeers functionality.
cl-refactor
Daniel Hams 11 years ago
parent
commit
f91609e247
  1. 44
      libethereum/PeerNetwork.cpp
  2. 4
      libethereum/PeerNetwork.h

44
libethereum/PeerNetwork.cpp

@ -60,14 +60,36 @@ static const vector<bi::address> c_rejectAddresses = {
{bi::address_v6::from_string("::")}
};
PeerSession::PeerSession(PeerServer* _s, bi::tcp::socket _socket, uint _rNId):
// Helper function to determine if an address falls within one of the reserved ranges
// For V4:
// Class A "10.*", Class B "172.[16->31].*", Class C "192.168.*"
// Not implemented yet for V6
bool eth::isPrivateAddress(bi::address _addressToCheck)
{
if (_addressToCheck.is_v4())
{
bi::address_v4 v4Address = _addressToCheck.to_v4();
bi::address_v4::bytes_type bytesToCheck = v4Address.to_bytes();
if (bytesToCheck[0] == 10)
return true;
if (bytesToCheck[0] == 172 && (bytesToCheck[1] >= 16 && bytesToCheck[1] <=31))
return true;
if (bytesToCheck[0] == 192 && bytesToCheck[1] == 168)
return true;
}
return false;
}
PeerSession::PeerSession(PeerServer* _s, bi::tcp::socket _socket, uint _rNId, bi::address _peerAddress, short _peerPort):
m_server(_s),
m_socket(std::move(_socket)),
m_reqNetworkId(_rNId),
m_listenPort(_peerPort),
m_rating(0)
{
m_disconnect = std::chrono::steady_clock::time_point::max();
m_connect = std::chrono::steady_clock::now();
m_info = PeerInfo({"?", _peerAddress.to_string(), m_listenPort, std::chrono::steady_clock::duration(0)});
}
PeerSession::~PeerSession()
@ -98,7 +120,8 @@ bool PeerSession::interpret(RLP const& _r)
m_networkId = _r[2].toInt<uint>();
auto clientVersion = _r[3].toString();
m_caps = _r[4].toInt<uint>();
m_listenPort = _r[5].toInt<short>();
if (_r.itemCount() > 5)
m_listenPort = _r[5].toInt<short>();
m_id = _r[6].toHash<h512>();
clogS(NetMessageSummary) << "Hello: " << clientVersion << "V[" << m_protocolVersion << "/" << m_networkId << "]" << asHex(m_id.ref().cropped(0, 4)) << showbase << hex << m_caps << dec << m_listenPort;
@ -116,7 +139,7 @@ bool PeerSession::interpret(RLP const& _r)
return false;
}
try
{ m_info = PeerInfo({clientVersion, m_socket.remote_endpoint().address().to_string(), (short)m_socket.remote_endpoint().port(), std::chrono::steady_clock::duration()}); }
{ m_info = PeerInfo({clientVersion, m_socket.remote_endpoint().address().to_string(), m_listenPort, std::chrono::steady_clock::duration()}); }
catch (...)
{
disconnect(BadProtocol);
@ -196,8 +219,11 @@ bool PeerSession::interpret(RLP const& _r)
clogS(NetMessageSummary) << "Peers (" << dec << (_r.itemCount() - 1) << " entries)";
for (unsigned i = 1; i < _r.itemCount(); ++i)
{
auto ep = bi::tcp::endpoint(bi::address_v4(_r[i][0].toArray<byte, 4>()), _r[i][1].toInt<short>());
bi::address_v4 peerAddress(_r[i][0].toArray<byte, 4>());
auto ep = bi::tcp::endpoint(peerAddress, _r[i][1].toInt<short>());
Public id = _r[i][2].toHash<Public>();
if (isPrivateAddress(peerAddress))
goto CONTINUE;
clogS(NetAllDetail) << "Checking: " << ep << "(" << asHex(id.ref().cropped(0, 4)) << ")";
@ -707,7 +733,9 @@ std::map<Public, bi::tcp::endpoint> PeerServer::potentialPeers()
if (auto j = i.second.lock())
{
auto ep = j->endpoint();
if (ep.port() && j->m_id)
// Skip peers with a listen port of zero or are on a private network
bool peerOnNet = (j->m_listenPort != 0 && !isPrivateAddress(ep.address()));
if (peerOnNet && ep.port() && j->m_id)
ret.insert(make_pair(i.first, ep));
}
return ret;
@ -727,7 +755,9 @@ void PeerServer::ensureAccepting()
try {
clog(NetNote) << "Accepted connection from " << m_socket.remote_endpoint();
} catch (...){}
auto p = std::make_shared<PeerSession>(this, std::move(m_socket), m_requiredNetworkId);
bi::address remoteAddress = m_socket.remote_endpoint().address();
// Port defaults to 0 - we let the hello tell us which port the peer listens to
auto p = std::make_shared<PeerSession>(this, std::move(m_socket), m_requiredNetworkId, remoteAddress);
p->start();
}
catch (std::exception const& _e)
@ -754,7 +784,7 @@ void PeerServer::connect(bi::tcp::endpoint const& _ep)
}
else
{
auto p = make_shared<PeerSession>(this, std::move(*s), m_requiredNetworkId);
auto p = make_shared<PeerSession>(this, std::move(*s), m_requiredNetworkId, _ep.address(), _ep.port());
clog(NetNote) << "Connected to " << p->endpoint();
p->start();
}

4
libethereum/PeerNetwork.h

@ -35,6 +35,8 @@ namespace bi = boost::asio::ip;
namespace eth
{
bool isPrivateAddress(bi::address _addressToCheck);
class BlockChain;
class TransactionQueue;
@ -89,7 +91,7 @@ class PeerSession: public std::enable_shared_from_this<PeerSession>
friend class PeerServer;
public:
PeerSession(PeerServer* _server, bi::tcp::socket _socket, uint _rNId);
PeerSession(PeerServer* _server, bi::tcp::socket _socket, uint _rNId, bi::address _peerAddress, short _peerPort = 0);
~PeerSession();
void start();

Loading…
Cancel
Save