| 395 | } |
| 396 | |
| 397 | void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet) |
| 398 | { |
| 399 | try { |
| 400 | unique_ptr<DiscoveryDatagram> packet = DiscoveryDatagram::interpretUDP(_from, _packet); |
| 401 | if (!packet) |
| 402 | return; |
| 403 | if (packet->isExpired()) |
| 404 | { |
| 405 | clog(NodeTableWarn) << "Invalid packet (timestamp in the past) from " << _from.address().to_string() << ":" << _from.port(); |
| 406 | return; |
| 407 | } |
| 408 | |
| 409 | switch (packet->packetType()) |
| 410 | { |
| 411 | case Pong::type: |
| 412 | { |
| 413 | auto in = dynamic_cast<Pong const&>(*packet); |
| 414 | // whenever a pong is received, check if it's in m_evictions |
| 415 | bool found = false; |
| 416 | EvictionTimeout evictionEntry; |
| 417 | DEV_GUARDED(x_evictions) |
| 418 | for (auto it = m_evictions.begin(); it != m_evictions.end(); ++it) |
| 419 | if (it->first.first == in.sourceid && it->first.second > std::chrono::steady_clock::now()) |
| 420 | { |
| 421 | found = true; |
| 422 | evictionEntry = *it; |
| 423 | m_evictions.erase(it); |
| 424 | break; |
| 425 | } |
| 426 | if (found) |
| 427 | { |
| 428 | if (auto n = nodeEntry(evictionEntry.second)) |
| 429 | dropNode(n); |
| 430 | if (auto n = nodeEntry(evictionEntry.first.first)) |
| 431 | n->pending = false; |
| 432 | } |
| 433 | else |
| 434 | { |
| 435 | // if not, check if it's known/pending or a pubk discovery ping |
| 436 | if (auto n = nodeEntry(in.sourceid)) |
| 437 | n->pending = false; |
| 438 | else |
| 439 | { |
| 440 | DEV_GUARDED(x_pubkDiscoverPings) |
| 441 | { |
| 442 | if (!m_pubkDiscoverPings.count(_from.address())) |
| 443 | return; // unsolicited pong; don't note node as active |
| 444 | m_pubkDiscoverPings.erase(_from.address()); |
| 445 | } |
| 446 | if (!haveNode(in.sourceid)) |
| 447 | addNode(Node(in.sourceid, NodeIPEndpoint(_from.address(), _from.port(), _from.port()))); |
| 448 | } |
| 449 | } |
| 450 | |
| 451 | // update our endpoint address and UDP port |
| 452 | DEV_GUARDED(x_nodes) |
| 453 | { |
| 454 | if ((!m_node.endpoint || !m_node.endpoint.isAllowed()) && isPublicAddress(in.destination.address)) |
no test coverage detected