Changeset View
Changeset View
Standalone View
Standalone View
src/protocol.cpp
Show First 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | static const std::string allNetMessageTypes[] = { | ||||
NetMsgType::CMPCTBLOCK, NetMsgType::GETBLOCKTXN, NetMsgType::BLOCKTXN, | NetMsgType::CMPCTBLOCK, NetMsgType::GETBLOCKTXN, NetMsgType::BLOCKTXN, | ||||
NetMsgType::GETCFILTERS, NetMsgType::CFILTER, NetMsgType::GETCFHEADERS, | NetMsgType::GETCFILTERS, NetMsgType::CFILTER, NetMsgType::GETCFHEADERS, | ||||
NetMsgType::CFHEADERS, NetMsgType::GETCFCHECKPT, NetMsgType::CFCHECKPT, | NetMsgType::CFHEADERS, NetMsgType::GETCFCHECKPT, NetMsgType::CFCHECKPT, | ||||
}; | }; | ||||
static const std::vector<std::string> | static const std::vector<std::string> | ||||
allNetMessageTypesVec(std::begin(allNetMessageTypes), | allNetMessageTypesVec(std::begin(allNetMessageTypes), | ||||
std::end(allNetMessageTypes)); | std::end(allNetMessageTypes)); | ||||
CMessageHeader::CMessageHeader(const MessageMagic &pchMessageStartIn) { | CMessageHeader::CMessageHeader() { | ||||
memcpy(std::begin(pchMessageStart), std::begin(pchMessageStartIn), | memset(std::begin(pchMessageStart), 0, MESSAGE_START_SIZE); | ||||
MESSAGE_START_SIZE); | |||||
memset(pchCommand.data(), 0, sizeof(pchCommand)); | memset(pchCommand.data(), 0, sizeof(pchCommand)); | ||||
nMessageSize = -1; | nMessageSize = -1; | ||||
memset(pchChecksum, 0, CHECKSUM_SIZE); | memset(pchChecksum, 0, CHECKSUM_SIZE); | ||||
} | } | ||||
CMessageHeader::CMessageHeader(const MessageMagic &pchMessageStartIn, | CMessageHeader::CMessageHeader(const MessageMagic &pchMessageStartIn, | ||||
const char *pszCommand, | const char *pszCommand, | ||||
unsigned int nMessageSizeIn) { | unsigned int nMessageSizeIn) { | ||||
Show All 16 Lines | |||||
std::string CMessageHeader::GetCommand() const { | std::string CMessageHeader::GetCommand() const { | ||||
// return std::string(pchCommand.begin(), pchCommand.end()); | // return std::string(pchCommand.begin(), pchCommand.end()); | ||||
return std::string(pchCommand.data(), | return std::string(pchCommand.data(), | ||||
pchCommand.data() + | pchCommand.data() + | ||||
strnlen(pchCommand.data(), COMMAND_SIZE)); | strnlen(pchCommand.data(), COMMAND_SIZE)); | ||||
} | } | ||||
static bool | static bool CheckHeaderMagicAndCommand(const CMessageHeader &header) { | ||||
CheckHeaderMagicAndCommand(const CMessageHeader &header, | |||||
const CMessageHeader::MessageMagic &magic) { | |||||
// Check start string | |||||
if (memcmp(std::begin(header.pchMessageStart), std::begin(magic), | |||||
CMessageHeader::MESSAGE_START_SIZE) != 0) { | |||||
return false; | |||||
} | |||||
// Check the command string for errors | // Check the command string for errors | ||||
for (const char *p1 = header.pchCommand.data(); | for (const char *p1 = header.pchCommand.data(); | ||||
p1 < header.pchCommand.data() + CMessageHeader::COMMAND_SIZE; p1++) { | p1 < header.pchCommand.data() + 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 < header.pchCommand.data() + CMessageHeader::COMMAND_SIZE; | for (; p1 < header.pchCommand.data() + CMessageHeader::COMMAND_SIZE; | ||||
p1++) { | 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; | return true; | ||||
} | } | ||||
bool CMessageHeader::IsValid(const Config &config) const { | bool CMessageHeader::IsCommandValid() const { | ||||
// Check start string | // Check start string | ||||
if (!CheckHeaderMagicAndCommand(*this, | 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 false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
/** | /** | ||||
* This is a transition method in order to stay compatible with older code that | * 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 | * 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 | * 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 | * bigger than the permitted size. Idealy, code that uses this function should | ||||
* be migrated toward using the config. | * be migrated toward using the config. | ||||
*/ | */ | ||||
bool CMessageHeader::IsValidWithoutConfig(const MessageMagic &magic) const { | bool CMessageHeader::IsValidWithoutConfig(const MessageMagic &magic) const { | ||||
// Check start string | // Check start string | ||||
if (!CheckHeaderMagicAndCommand(*this, magic)) { | if (!CheckHeaderMagicAndCommand(*this)) { | ||||
return false; | |||||
} | |||||
// Message size | |||||
if (nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) { | |||||
LogPrintf( | |||||
"CMessageHeader::IsValidForSeeder(): (%s, %u bytes) is oversized\n", | |||||
GetCommand(), nMessageSize); | |||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CMessageHeader::IsOversized(const Config &config) const { | bool CMessageHeader::IsOversized(const Config &config) const { | ||||
// If the message doesn't not contain a block content, check against | // If the message doesn't not contain a block content, check against | ||||
▲ Show 20 Lines • Show All 101 Lines • Show Last 20 Lines |