Browse Source

adopt node IP address from udp header when ping.ipAddress isn't public

cl-refactor
subtly 10 years ago
parent
commit
015c1681fb
  1. 8
      libp2p/Host.cpp
  2. 26
      libp2p/NodeTable.cpp
  3. 34
      test/net.cpp

8
libp2p/Host.cpp

@ -592,13 +592,13 @@ void Host::startedWorking()
m_run = true;
}
// try to open acceptor (todo: ipv6)
m_listenPort = Network::tcp4Listen(m_tcp4Acceptor, m_netPrefs.listenPort);
// start capability threads
// start capability threads (ready for incoming connections)
for (auto const& h: m_capabilities)
h.second->onStarting();
// try to open acceptor (todo: ipv6)
m_listenPort = Network::tcp4Listen(m_tcp4Acceptor, m_netPrefs.listenPort);
// determine public IP, but only if we're able to listen for connections
// todo: GUI when listen is unavailable in UI
if (m_listenPort)

26
libp2p/NodeTable.cpp

@ -84,11 +84,14 @@ shared_ptr<NodeEntry> NodeTable::addNode(Node const& _node)
return move(shared_ptr<NodeEntry>());
}
// ping address if nodeid is empty
// ping address to recover nodeid if nodeid is empty
if (!_node.id)
{
clog(NodeTableConnect) << "Sending public key discovery Ping to" << _node.endpoint.udp << "(Advertising:" << m_node.endpoint.udp << ")";
{
Guard l(x_pubkDiscoverPings);
m_pubkDiscoverPings[_node.endpoint.udp.address()] = std::chrono::steady_clock::now();
}
PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port());
p.sign(m_secret);
m_socketPointer->send(p);
@ -101,7 +104,11 @@ shared_ptr<NodeEntry> NodeTable::addNode(Node const& _node)
return m_nodes[_node.id];
}
shared_ptr<NodeEntry> ret(new NodeEntry(m_node, _node.id, NodeIPEndpoint(_node.endpoint.udp, _node.endpoint.tcp)));
// TODO: SECURITY - Temporary until packets are updated.
NodeIPEndpoint ep(_node.endpoint.udp, _node.endpoint.tcp);
if (!isPublicAddress(ep.tcp.address()))
ep.tcp.address(_node.endpoint.udp.address());
shared_ptr<NodeEntry> ret(new NodeEntry(m_node, _node.id, ep));
m_nodes[_node.id] = ret;
PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port());
p.sign(m_secret);
@ -315,9 +322,13 @@ void NodeTable::noteActiveNode(Public const& _pubk, bi::udp::endpoint const& _en
{
clog(NodeTableConnect) << "Noting active node:" << _pubk.abridged() << _endpoint.address().to_string() << ":" << _endpoint.port();
// update udp endpoint
// TODO: SECURITY - Temporary until packets are updated.
// update udp endpoint and override tcp endpoint if tcp endpoint isn't public
// (for the rare case where NAT port is mapped but
node->endpoint.udp.address(_endpoint.address());
node->endpoint.udp.port(_endpoint.port());
if (!isPublicAddress(node->endpoint.tcp.address()))
node->endpoint.tcp.address(_endpoint.address());
shared_ptr<NodeEntry> contested;
{
@ -399,7 +410,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
bytesConstRef signedBytes(hashedBytes.cropped(Signature::size, hashedBytes.size() - Signature::size));
// todo: verify sig via known-nodeid and MDC, or, do ping/pong auth if node/endpoint is unknown/untrusted
// todo: verify sig via known-nodeid and MDC
bytesConstRef sigBytes(_packet.cropped(h256::size, Signature::size));
Public nodeid(dev::recover(*(Signature const*)sigBytes.data(), sha3(signedBytes)));
@ -430,7 +441,6 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
dropNode(n);
if (auto n = nodeEntry(it->first.first))
if (m_nodeEventHandler && n->pending)
n->pending = false;
it = m_evictions.erase(it);
@ -441,14 +451,18 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
{
if (auto n = nodeEntry(nodeid))
n->pending = false;
}
else if (m_pubkDiscoverPings.count(_from.address()))
{
{
Guard l(x_pubkDiscoverPings);
m_pubkDiscoverPings.erase(_from.address());
}
if (!haveNode(nodeid))
addNode(nodeid, _from, bi::tcp::endpoint(_from.address(), _from.port()));
}
else
return; // unsolicited pong; don't note node as active
}
break;
}

34
test/net.cpp

@ -145,6 +145,40 @@ public:
bool success = false;
};
BOOST_AUTO_TEST_CASE(isIPAddressType)
{
string wildcard = "0.0.0.0";
BOOST_REQUIRE(bi::address::from_string(wildcard).is_unspecified());
string empty = "";
BOOST_REQUIRE_THROW(bi::address::from_string(empty).is_unspecified(), std::exception);
string publicAddress192 = "192.169.0.0";
BOOST_REQUIRE(isPublicAddress(publicAddress192));
BOOST_REQUIRE(!isPrivateAddress(publicAddress192));
BOOST_REQUIRE(!isLocalHostAddress(publicAddress192));
string publicAddress172 = "172.32.0.0";
BOOST_REQUIRE(isPublicAddress(publicAddress172));
BOOST_REQUIRE(!isPrivateAddress(publicAddress172));
BOOST_REQUIRE(!isLocalHostAddress(publicAddress172));
string privateAddress192 = "192.168.1.0";
BOOST_REQUIRE(isPrivateAddress(privateAddress192));
BOOST_REQUIRE(!isPublicAddress(privateAddress192));
BOOST_REQUIRE(!isLocalHostAddress(privateAddress192));
string privateAddress172 = "172.16.0.0";
BOOST_REQUIRE(isPrivateAddress(privateAddress172));
BOOST_REQUIRE(!isPublicAddress(privateAddress172));
BOOST_REQUIRE(!isLocalHostAddress(privateAddress172));
string privateAddress10 = "10.0.0.0";
BOOST_REQUIRE(isPrivateAddress(privateAddress10));
BOOST_REQUIRE(!isPublicAddress(privateAddress10));
BOOST_REQUIRE(!isLocalHostAddress(privateAddress10));
}
BOOST_AUTO_TEST_CASE(v2PingNodePacket)
{
// test old versino of pingNode packet w/new

Loading…
Cancel
Save