Changeset View
Changeset View
Standalone View
Standalone View
src/protocol.cpp
// Copyright (c) 2009-2010 Satoshi Nakamoto | // Copyright (c) 2009-2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2016 The Bitcoin Core developers | // Copyright (c) 2009-2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include "protocol.h" | #include "protocol.h" | ||||
#include "chainparams.h" | |||||
#include "config.h" | |||||
#include "util.h" | #include "util.h" | ||||
#include "utilstrencodings.h" | #include "utilstrencodings.h" | ||||
#ifndef WIN32 | #ifndef WIN32 | ||||
#include <arpa/inet.h> | #include <arpa/inet.h> | ||||
#endif | #endif | ||||
namespace NetMsgType { | namespace NetMsgType { | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | CMessageHeader::CMessageHeader(const MessageMagic &pchMessageStartIn, | ||||
memset(pchChecksum, 0, CHECKSUM_SIZE); | memset(pchChecksum, 0, CHECKSUM_SIZE); | ||||
} | } | ||||
std::string CMessageHeader::GetCommand() const { | std::string CMessageHeader::GetCommand() const { | ||||
return std::string(pchCommand, | return std::string(pchCommand, | ||||
pchCommand + strnlen(pchCommand, COMMAND_SIZE)); | pchCommand + strnlen(pchCommand, COMMAND_SIZE)); | ||||
} | } | ||||
bool CMessageHeader::IsValid(const MessageMagic &pchMessageStartIn) const { | static bool | ||||
CheckHeaderMagicAndCommand(const CMessageHeader &header, | |||||
const CMessageHeader::MessageMagic &magic) { | |||||
// Check start string | // Check start string | ||||
if (memcmp(std::begin(pchMessageStart), std::begin(pchMessageStartIn), | if (memcmp(std::begin(header.pchMessageStart), std::begin(magic), | ||||
MESSAGE_START_SIZE) != 0) { | CMessageHeader::MESSAGE_START_SIZE) != 0) { | ||||
return false; | return false; | ||||
} | } | ||||
// Check the command string for errors | // Check the command string for errors | ||||
for (const char *p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++) { | for (const char *p1 = header.pchCommand; | ||||
p1 < header.pchCommand + CMessageHeader::COMMAND_SIZE; p1++) { | |||||
if (*p1 == 0) { | if (*p1 == 0) { | ||||
// Must be all zeros after the first zero | // Must be all zeros after the first zero | ||||
for (; p1 < pchCommand + COMMAND_SIZE; p1++) { | for (; p1 < header.pchCommand + CMessageHeader::COMMAND_SIZE; | ||||
p1++) { | |||||
if (*p1 != 0) { | if (*p1 != 0) { | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
} else if (*p1 < ' ' || *p1 > 0x7E) { | } else if (*p1 < ' ' || *p1 > 0x7E) { | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
return true; | |||||
} | |||||
bool CMessageHeader::IsValid(const Config &config) const { | |||||
// Check start string | |||||
if (!CheckHeaderMagicAndCommand(*this, | |||||
config.GetChainParams().NetMagic())) { | |||||
return false; | |||||
} | |||||
// Message size | |||||
if (IsOversized(config)) { | |||||
LogPrintf("CMessageHeader::IsValid(): (%s, %u bytes) is oversized\n", | |||||
GetCommand(), nMessageSize); | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
/** | |||||
* This is a transition method in order to stay compatible with older code that | |||||
* do not use the config. It assumes message will not get too large. This cannot | |||||
* be used for any piece of code that will download blocks as blocks may be | |||||
* bigger than the permitted size. Idealy, code that uses this function should | |||||
* be migrated toward using the config. | |||||
*/ | |||||
bool CMessageHeader::IsValidWithoutConfig(const MessageMagic &magic) const { | |||||
// Check start string | |||||
if (!CheckHeaderMagicAndCommand(*this, magic)) { | |||||
return false; | |||||
} | |||||
// Message size | // Message size | ||||
if (nMessageSize > MAX_SIZE) { | if (nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) { | ||||
LogPrintf("CMessageHeader::IsValid(): (%s, %u bytes) nMessageSize > " | LogPrintf( | ||||
"MAX_SIZE\n", | "CMessageHeader::IsValidForSeeder(): (%s, %u bytes) is oversized\n", | ||||
GetCommand(), nMessageSize); | GetCommand(), nMessageSize); | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CMessageHeader::IsOversized(const Config &config) const { | |||||
// If the message doesn't not contain a block content, check against | |||||
// MAX_PROTOCOL_MESSAGE_LENGTH. | |||||
if (nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH && | |||||
!NetMsgType::IsBlockLike(GetCommand())) { | |||||
return true; | |||||
} | |||||
// Scale the maximum accepted size with the block size. | |||||
if (nMessageSize > 2 * config.GetMaxBlockSize()) { | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
CAddress::CAddress() : CService() { | CAddress::CAddress() : CService() { | ||||
Init(); | Init(); | ||||
} | } | ||||
CAddress::CAddress(CService ipIn, ServiceFlags nServicesIn) : CService(ipIn) { | CAddress::CAddress(CService ipIn, ServiceFlags nServicesIn) : CService(ipIn) { | ||||
Init(); | Init(); | ||||
nServices = nServicesIn; | nServices = nServicesIn; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 49 Lines • Show Last 20 Lines |