Bypass non-nSPV messages
This commit is contained in:
215
src/main.cpp
215
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<CAddress> 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<CAddress> 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();
|
||||
|
||||
Reference in New Issue
Block a user