lbrycrd/src/protocol.cpp
Wladimir J. van der Laan 62e5f8f961 CMessageHeader sanity changes
- Remove spurious `pchCommand[1] = 1` in CMessageHeader()
- Make sure that pchCommand is zero-padded if length is shorter than
  COMMAND_SIZE
- Use strnlen to determine length of pcmCommand in GetCommand
2014-09-18 10:15:48 +02:00

143 lines
3.2 KiB
C++

// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "protocol.h"
#include "chainparams.h"
#include "util.h"
#ifndef WIN32
# include <arpa/inet.h>
#endif
static const char* ppszTypeName[] =
{
"ERROR",
"tx",
"block",
"filtered block"
};
CMessageHeader::CMessageHeader()
{
memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
memset(pchCommand, 0, sizeof(pchCommand));
nMessageSize = -1;
nChecksum = 0;
}
CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
{
memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
memset(pchCommand, 0, sizeof(pchCommand));
strncpy(pchCommand, pszCommand, COMMAND_SIZE);
nMessageSize = nMessageSizeIn;
nChecksum = 0;
}
std::string CMessageHeader::GetCommand() const
{
return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
}
bool CMessageHeader::IsValid() const
{
// Check start string
if (memcmp(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0)
return false;
// Check the command string for errors
for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
{
if (*p1 == 0)
{
// Must be all zeros after the first zero
for (; p1 < pchCommand + COMMAND_SIZE; p1++)
if (*p1 != 0)
return false;
}
else if (*p1 < ' ' || *p1 > 0x7E)
return false;
}
// Message size
if (nMessageSize > MAX_SIZE)
{
LogPrintf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize);
return false;
}
return true;
}
CAddress::CAddress() : CService()
{
Init();
}
CAddress::CAddress(CService ipIn, uint64_t nServicesIn) : CService(ipIn)
{
Init();
nServices = nServicesIn;
}
void CAddress::Init()
{
nServices = NODE_NETWORK;
nTime = 100000000;
nLastTry = 0;
}
CInv::CInv()
{
type = 0;
hash = 0;
}
CInv::CInv(int typeIn, const uint256& hashIn)
{
type = typeIn;
hash = hashIn;
}
CInv::CInv(const std::string& strType, const uint256& hashIn)
{
unsigned int i;
for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
{
if (strType == ppszTypeName[i])
{
type = i;
break;
}
}
if (i == ARRAYLEN(ppszTypeName))
throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType));
hash = hashIn;
}
bool operator<(const CInv& a, const CInv& b)
{
return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
}
bool CInv::IsKnownType() const
{
return (type >= 1 && type < (int)ARRAYLEN(ppszTypeName));
}
const char* CInv::GetCommand() const
{
if (!IsKnownType())
throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
return ppszTypeName[type];
}
std::string CInv::ToString() const
{
return strprintf("%s %s", GetCommand(), hash.ToString());
}