X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fmain.cpp;h=f6adb17281915fa33f81bb4c93fdadaee6a65b72;hb=47bb141bf2d589db630ac1a917189b05b75b80d0;hp=9ff24e482f648e109e4b4cf023f0a21ce72a8dd5;hpb=ad42655e7a1f22e2a75e14ad73776367229ed081;p=novacoin.git diff --git a/src/main.cpp b/src/main.cpp index 9ff24e4..f6adb17 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -511,6 +511,10 @@ bool CTransaction::CheckTransaction() const return DoS(10, error("CTransaction::CheckTransaction() : vin empty")); if (vout.empty()) return DoS(10, error("CTransaction::CheckTransaction() : vout empty")); + // Time (prevent mempool memory exhaustion attack) + // Comes into force since 20 December 2015. + if (nTime > 1450569600 && nTime > FutureDrift(GetAdjustedTime())) + return DoS(10, error("CTransaction::CheckTransaction() : timestamp is too far into the future")); // Size limits if (::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) return DoS(100, error("CTransaction::CheckTransaction() : size limits failed")); @@ -2335,10 +2339,19 @@ bool CBlock::AcceptBlock() if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake())) return DoS(100, error("AcceptBlock() : incorrect %s", IsProofOfWork() ? "proof-of-work" : "proof-of-stake")); + int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); + int nMaxOffset = 12 * 3600; // 12 hours + if (pindexPrev->nTime < 1450569600) + nMaxOffset = 7 * 86400; // One week until 20 Dec, 2015 + // Check timestamp against prev - if (GetBlockTime() <= pindexPrev->GetMedianTimePast() || FutureDrift(GetBlockTime()) < pindexPrev->GetBlockTime()) + if (GetBlockTime() <= nMedianTimePast || FutureDrift(GetBlockTime()) < pindexPrev->GetBlockTime()) return error("AcceptBlock() : block's timestamp is too early"); + // Don't accept blocks with future timestamps + if (pindexPrev->nHeight > 1 && nMedianTimePast + nMaxOffset < GetBlockTime()) + return error("AcceptBlock() : block's timestamp is too far in the future"); + // Check that all transactions are finalized BOOST_FOREACH(const CTransaction& tx, vtx) if (!tx.IsFinal(nHeight, GetBlockTime())) @@ -2675,7 +2688,7 @@ static filesystem::path BlockFilePath(unsigned int nFile) FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode) { - if ((nFile < 1) || (nFile == (unsigned int) -1)) + if ((nFile < 1) || (nFile == std::numeric_limits::max())) return NULL; FILE* file = fopen(BlockFilePath(nFile).string().c_str(), pszMode); if (!file) @@ -2942,7 +2955,7 @@ bool LoadExternalBlockFile(FILE* fileIn) try { CAutoFile blkdat(fileIn, SER_DISK, CLIENT_VERSION); unsigned int nPos = 0; - while (nPos != (unsigned int)-1 && blkdat.good() && !fRequestShutdown) + while (nPos != std::numeric_limits::max() && blkdat.good() && !fRequestShutdown) { unsigned char pchData[65536]; do { @@ -2950,7 +2963,7 @@ bool LoadExternalBlockFile(FILE* fileIn) int nRead = fread(pchData, 1, sizeof(pchData), blkdat); if (nRead <= 8) { - nPos = (unsigned int)-1; + nPos = std::numeric_limits::max(); break; } void* nFind = memchr(pchData, pchMessageStart[0], nRead+1-sizeof(pchMessageStart)); @@ -2966,7 +2979,7 @@ bool LoadExternalBlockFile(FILE* fileIn) else nPos += sizeof(pchData) - sizeof(pchMessageStart) + 1; } while(!fRequestShutdown); - if (nPos == (unsigned int)-1) + if (nPos == std::numeric_limits::max()) break; fseek(blkdat, nPos, SEEK_SET); unsigned int nSize; @@ -3335,7 +3348,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } // find last block in inv vector - unsigned int nLastBlock = (unsigned int)(-1); + unsigned int nLastBlock = std::numeric_limits::max(); for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) { if (vInv[vInv.size() - 1 - nInv].type == MSG_BLOCK) { nLastBlock = vInv.size() - 1 - nInv; @@ -3619,7 +3632,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } - else if (strCommand == "getaddr") + // 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 users (which are behind NAT and can only make outgoing connections) ignore + // getaddr message mitigates the attack. + else if ((strCommand == "getaddr") && (pfrom->fInbound)) { // Don't return addresses older than nCutOff timestamp int64_t nCutOff = GetTime() - (nNodeLifespan * nOneDay); @@ -4070,4 +4088,4 @@ public: // orphan transactions } -} instance_of_cmaincleanup; \ No newline at end of file +} instance_of_cmaincleanup;