| 5650 | } |
| 5651 | |
| 5652 | void PeerManagerImpl::ProcessPong(CNode& pfrom, Peer& peer, const NodeClock::time_point ping_end, DataStream& vRecv) |
| 5653 | { |
| 5654 | uint64_t nonce = 0; |
| 5655 | const size_t nAvail{vRecv.size()}; |
| 5656 | bool bPingFinished = false; |
| 5657 | std::string sProblem; |
| 5658 | |
| 5659 | if (nAvail >= sizeof(nonce)) { |
| 5660 | vRecv >> nonce; |
| 5661 | |
| 5662 | // Only process pong message if there is an outstanding ping (old ping without nonce should never pong) |
| 5663 | if (peer.m_ping_nonce_sent != 0) { |
| 5664 | if (nonce == peer.m_ping_nonce_sent) { |
| 5665 | // Matching pong received, this ping is no longer outstanding |
| 5666 | bPingFinished = true; |
| 5667 | const auto ping_time = ping_end - peer.m_ping_start.load(); |
| 5668 | if (ping_time.count() >= 0) { |
| 5669 | // Let connman know about this successful ping-pong |
| 5670 | pfrom.PongReceived(ping_time); |
| 5671 | if (pfrom.IsPrivateBroadcastConn()) { |
| 5672 | m_tx_for_private_broadcast.NodeConfirmedReception(pfrom.GetId()); |
| 5673 | LogDebug(BCLog::PRIVBROADCAST, "Got a PONG (the transaction will probably reach the network), marking for disconnect, %s", |
| 5674 | pfrom.LogPeer()); |
| 5675 | pfrom.fDisconnect = true; |
| 5676 | } |
| 5677 | } else { |
| 5678 | // This should never happen |
| 5679 | sProblem = "Timing mishap"; |
| 5680 | } |
| 5681 | } else { |
| 5682 | // Nonce mismatches are normal when pings are overlapping |
| 5683 | sProblem = "Nonce mismatch"; |
| 5684 | if (nonce == 0) { |
| 5685 | // This is most likely a bug in another implementation somewhere; cancel this ping |
| 5686 | bPingFinished = true; |
| 5687 | sProblem = "Nonce zero"; |
| 5688 | } |
| 5689 | } |
| 5690 | } else { |
| 5691 | sProblem = "Unsolicited pong without ping"; |
| 5692 | } |
| 5693 | } else { |
| 5694 | // This is most likely a bug in another implementation somewhere; cancel this ping |
| 5695 | bPingFinished = true; |
| 5696 | sProblem = "Short payload"; |
| 5697 | } |
| 5698 | |
| 5699 | if (!(sProblem.empty())) { |
| 5700 | LogDebug(BCLog::NET, "pong peer=%d: %s, %x expected, %x received, %u bytes\n", |
| 5701 | pfrom.GetId(), |
| 5702 | sProblem, |
| 5703 | peer.m_ping_nonce_sent, |
| 5704 | nonce, |
| 5705 | nAvail); |
| 5706 | } |
| 5707 | if (bPingFinished) { |
| 5708 | peer.m_ping_nonce_sent = 0; |
| 5709 | } |
nothing calls this directly
no test coverage detected