Browse Source

Merge pull request #37 from danielhams/peerportfixes

Peer Address And Port Fixes
cl-refactor
Gav Wood 11 years ago
parent
commit
5b34345464
  1. 41
      libethereum/PeerNetwork.cpp
  2. 4
      libethereum/PeerNetwork.h

41
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()
@ -116,7 +138,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 +218,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 +732,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 +754,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 +783,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