diff --git a/src/main.cpp b/src/main.cpp index fa7362bfd..2f1280506 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7313,7 +7313,112 @@ fprintf(stderr, "recv: %s peer=%d\n", SanitizeString(strCommand).c_str(), (int32 if (pfrom->fOneShot) pfrom->fDisconnect = true; } + else if (strCommand == "ping") + { + if (pfrom->nVersion > BIP0031_VERSION) + { + uint64_t nonce = 0; + vRecv >> nonce; + // Echo the message back with the nonce. This allows for two useful features: + // + // 1) A remote node can quickly check if the connection is operational + // 2) Remote nodes can measure the latency of the network thread. If this node + // is overloaded it won't respond to pings quickly and the remote node can + // avoid sending us more work, like chain download requests. + // + // The nonce stops the remote getting confused between different pings: without + // it, if the remote node sends a ping once per second and this node takes 5 + // seconds to respond to each, the 5th ping the remote sends would appear to + // return very quickly. + pfrom->PushMessage("pong", nonce); + } + } + + + else if (strCommand == "pong") + { + int64_t pingUsecEnd = nTimeReceived; + uint64_t nonce = 0; + size_t nAvail = vRecv.in_avail(); + bool bPingFinished = false; + std::string sProblem; + + if (nAvail >= sizeof(nonce)) { + vRecv >> nonce; + + // Only process pong message if there is an outstanding ping (old ping without nonce should never pong) + if (pfrom->nPingNonceSent != 0) { + if (nonce == pfrom->nPingNonceSent) { + // Matching pong received, this ping is no longer outstanding + bPingFinished = true; + int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart; + if (pingUsecTime > 0) { + // Successful ping time measurement, replace previous + pfrom->nPingUsecTime = pingUsecTime; + pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime); + } else { + // This should never happen + sProblem = "Timing mishap"; + } + } else { + // Nonce mismatches are normal when pings are overlapping + sProblem = "Nonce mismatch"; + if (nonce == 0) { + // This is most likely a bug in another implementation somewhere; cancel this ping + bPingFinished = true; + sProblem = "Nonce zero"; + } + } + } else { + sProblem = "Unsolicited pong without ping"; + } + } else { + // This is most likely a bug in another implementation somewhere; cancel this ping + bPingFinished = true; + sProblem = "Short payload"; + } + + if (!(sProblem.empty())) { + LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n", + pfrom->id, + pfrom->cleanSubVer, + sProblem, + pfrom->nPingNonceSent, + nonce, + nAvail); + } + if (bPingFinished) { + pfrom->nPingNonceSent = 0; + } + } + // This asymmetric behavior for inbound and outbound connections was introduced + // to prevent a fingerprinting attack: an attacker can send specific fake addresses + // to users' AddrMan and later request them by sending getaddr messages. + // Making nodes which are behind NAT and can only make outgoing connections ignore + // the getaddr message mitigates the attack. + else if ((strCommand == "getaddr") && (pfrom->fInbound)) + { + // Only send one GetAddr response per connection to reduce resource waste + // and discourage addr stamping of INV announcements. + if (pfrom->fSentAddr) { + LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n", pfrom->id); + return true; + } + pfrom->fSentAddr = true; + + pfrom->vAddrToSend.clear(); + vector vAddr = addrman.GetAddr(); + BOOST_FOREACH(const CAddress &addr, vAddr) + pfrom->PushAddress(addr); + } + + else if ( KOMODO_NSPV != 0 ) + { + // handle addressutxos, addresstxids, notarizations, ... messages + fprintf(stderr,"ignore message %s\n",strCommand); + return; + } else if (strCommand == "inv") { @@ -7726,28 +7831,6 @@ fprintf(stderr, "recv: %s peer=%d\n", SanitizeString(strCommand).c_str(), (int32 } - // This asymmetric behavior for inbound and outbound connections was introduced - // to prevent a fingerprinting attack: an attacker can send specific fake addresses - // to users' AddrMan and later request them by sending getaddr messages. - // Making nodes which are behind NAT and can only make outgoing connections ignore - // the getaddr message mitigates the attack. - else if ((strCommand == "getaddr") && (pfrom->fInbound)) - { - // Only send one GetAddr response per connection to reduce resource waste - // and discourage addr stamping of INV announcements. - if (pfrom->fSentAddr) { - LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n", pfrom->id); - return true; - } - pfrom->fSentAddr = true; - - pfrom->vAddrToSend.clear(); - vector vAddr = addrman.GetAddr(); - BOOST_FOREACH(const CAddress &addr, vAddr) - pfrom->PushAddress(addr); - } - - else if (strCommand == "mempool") { LOCK2(cs_main, pfrom->cs_filter); @@ -7772,88 +7855,6 @@ fprintf(stderr, "recv: %s peer=%d\n", SanitizeString(strCommand).c_str(), (int32 if (vInv.size() > 0) pfrom->PushMessage("inv", vInv); } - - - else if (strCommand == "ping") - { - if (pfrom->nVersion > BIP0031_VERSION) - { - uint64_t nonce = 0; - vRecv >> nonce; - // Echo the message back with the nonce. This allows for two useful features: - // - // 1) A remote node can quickly check if the connection is operational - // 2) Remote nodes can measure the latency of the network thread. If this node - // is overloaded it won't respond to pings quickly and the remote node can - // avoid sending us more work, like chain download requests. - // - // The nonce stops the remote getting confused between different pings: without - // it, if the remote node sends a ping once per second and this node takes 5 - // seconds to respond to each, the 5th ping the remote sends would appear to - // return very quickly. - pfrom->PushMessage("pong", nonce); - } - } - - - else if (strCommand == "pong") - { - int64_t pingUsecEnd = nTimeReceived; - uint64_t nonce = 0; - size_t nAvail = vRecv.in_avail(); - bool bPingFinished = false; - std::string sProblem; - - if (nAvail >= sizeof(nonce)) { - vRecv >> nonce; - - // Only process pong message if there is an outstanding ping (old ping without nonce should never pong) - if (pfrom->nPingNonceSent != 0) { - if (nonce == pfrom->nPingNonceSent) { - // Matching pong received, this ping is no longer outstanding - bPingFinished = true; - int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart; - if (pingUsecTime > 0) { - // Successful ping time measurement, replace previous - pfrom->nPingUsecTime = pingUsecTime; - pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime); - } else { - // This should never happen - sProblem = "Timing mishap"; - } - } else { - // Nonce mismatches are normal when pings are overlapping - sProblem = "Nonce mismatch"; - if (nonce == 0) { - // This is most likely a bug in another implementation somewhere; cancel this ping - bPingFinished = true; - sProblem = "Nonce zero"; - } - } - } else { - sProblem = "Unsolicited pong without ping"; - } - } else { - // This is most likely a bug in another implementation somewhere; cancel this ping - bPingFinished = true; - sProblem = "Short payload"; - } - - if (!(sProblem.empty())) { - LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n", - pfrom->id, - pfrom->cleanSubVer, - sProblem, - pfrom->nPingNonceSent, - nonce, - nAvail); - } - if (bPingFinished) { - pfrom->nPingNonceSent = 0; - } - } - - else if (fAlerts && strCommand == "alert") { CAlert alert; @@ -8207,7 +8208,11 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } state.fShouldBan = false; } - + if ( KOMODO_NSPV != 0 ) + { + // issue getaddressutxos, ... + return(true); + } BOOST_FOREACH(const CBlockReject& reject, state.rejects) pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock); state.rejects.clear();