Bypass non-nSPV messages
This commit is contained in:
215
src/main.cpp
215
src/main.cpp
@@ -7313,8 +7313,113 @@ fprintf(stderr, "recv: %s peer=%d\n", SanitizeString(strCommand).c_str(), (int32
|
|||||||
if (pfrom->fOneShot)
|
if (pfrom->fOneShot)
|
||||||
pfrom->fDisconnect = true;
|
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")
|
else if (strCommand == "inv")
|
||||||
{
|
{
|
||||||
vector<CInv> vInv;
|
vector<CInv> vInv;
|
||||||
@@ -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")
|
else if (strCommand == "mempool")
|
||||||
{
|
{
|
||||||
LOCK2(cs_main, pfrom->cs_filter);
|
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)
|
if (vInv.size() > 0)
|
||||||
pfrom->PushMessage("inv", vInv);
|
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")
|
else if (fAlerts && strCommand == "alert")
|
||||||
{
|
{
|
||||||
CAlert alert;
|
CAlert alert;
|
||||||
@@ -8207,7 +8208,11 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
|||||||
}
|
}
|
||||||
state.fShouldBan = false;
|
state.fShouldBan = false;
|
||||||
}
|
}
|
||||||
|
if ( KOMODO_NSPV != 0 )
|
||||||
|
{
|
||||||
|
// issue getaddressutxos, ...
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
BOOST_FOREACH(const CBlockReject& reject, state.rejects)
|
BOOST_FOREACH(const CBlockReject& reject, state.rejects)
|
||||||
pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
|
pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
|
||||||
state.rejects.clear();
|
state.rejects.clear();
|
||||||
|
|||||||
Reference in New Issue
Block a user