Changeset View
Changeset View
Standalone View
Standalone View
src/net.cpp
Show First 20 Lines • Show All 564 Lines • ▼ Show 20 Lines | void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap) { | ||||
stats.m_ping_wait_usec = nPingUsecWait; | stats.m_ping_wait_usec = nPingUsecWait; | ||||
// Leave string empty if addrLocal invalid (not filled in yet) | // Leave string empty if addrLocal invalid (not filled in yet) | ||||
CService addrLocalUnlocked = GetAddrLocal(); | CService addrLocalUnlocked = GetAddrLocal(); | ||||
stats.addrLocal = | stats.addrLocal = | ||||
addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : ""; | addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : ""; | ||||
} | } | ||||
static bool IsOversizedMessage(const Config &config, | |||||
const TransportDeserializer &deserializer) { | |||||
if (!deserializer.in_data) { | |||||
// Header only, cannot be oversized. | |||||
return false; | |||||
} | |||||
return deserializer.hdr.IsOversized(config); | |||||
} | |||||
bool CNode::ReceiveMsgBytes(const Config &config, const char *pch, | bool CNode::ReceiveMsgBytes(const Config &config, const char *pch, | ||||
uint32_t nBytes, bool &complete) { | uint32_t nBytes, bool &complete) { | ||||
complete = false; | complete = false; | ||||
int64_t nTimeMicros = GetTimeMicros(); | int64_t nTimeMicros = GetTimeMicros(); | ||||
LOCK(cs_vRecv); | LOCK(cs_vRecv); | ||||
nLastRecv = nTimeMicros / 1000000; | nLastRecv = nTimeMicros / 1000000; | ||||
nRecvBytes += nBytes; | nRecvBytes += nBytes; | ||||
while (nBytes > 0) { | while (nBytes > 0) { | ||||
// Absorb network data. | // Absorb network data. | ||||
int handled; | int handled = m_deserializer->Read(config, pch, nBytes); | ||||
if (!m_deserializer->in_data) { | |||||
handled = m_deserializer->readHeader(config, pch, nBytes); | |||||
} else { | |||||
handled = m_deserializer->readData(pch, nBytes); | |||||
} | |||||
if (handled < 0) { | if (handled < 0) { | ||||
m_deserializer->Reset(); | m_deserializer->Reset(); | ||||
return false; | return false; | ||||
} | } | ||||
if (IsOversizedMessage(config, *m_deserializer)) { | if (m_deserializer->OversizedMessageDetected(config)) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"Oversized message from peer=%i, disconnecting\n", | "Oversized message from peer=%i, disconnecting\n", | ||||
GetId()); | GetId()); | ||||
m_deserializer->Reset(); | m_deserializer->Reset(); | ||||
return false; | return false; | ||||
} | } | ||||
pch += handled; | pch += handled; | ||||
nBytes -= handled; | nBytes -= handled; | ||||
if (m_deserializer->complete()) { | if (m_deserializer->Complete()) { | ||||
// decompose a transport agnostic CNetMessage from the deserializer | // decompose a transport agnostic CNetMessage from the deserializer | ||||
CNetMessage msg = m_deserializer->GetMessage(config, nTimeMicros); | CNetMessage msg = m_deserializer->GetMessage(config, nTimeMicros); | ||||
// Store received bytes per message command to prevent a memory DOS, | // Store received bytes per message command to prevent a memory DOS, | ||||
// only allow valid commands. | // only allow valid commands. | ||||
mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find( | mapMsgCmdSize::iterator i = | ||||
m_deserializer->hdr.pchCommand.data()); | mapRecvBytesPerMsgCmd.find(msg.m_command); | ||||
if (i == mapRecvBytesPerMsgCmd.end()) { | if (i == mapRecvBytesPerMsgCmd.end()) { | ||||
i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER); | i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER); | ||||
} | } | ||||
assert(i != mapRecvBytesPerMsgCmd.end()); | assert(i != mapRecvBytesPerMsgCmd.end()); | ||||
i->second += msg.m_raw_message_size; | i->second += msg.m_raw_message_size; | ||||
// push the message to the process queue, | // push the message to the process queue, | ||||
Show All 27 Lines | int CNode::GetSendVersion() const { | ||||
if (nSendVersion == 0) { | if (nSendVersion == 0) { | ||||
error("Requesting unset send version for node: %i. Using %i", id, | error("Requesting unset send version for node: %i. Using %i", id, | ||||
INIT_PROTO_VERSION); | INIT_PROTO_VERSION); | ||||
return INIT_PROTO_VERSION; | return INIT_PROTO_VERSION; | ||||
} | } | ||||
return nSendVersion; | return nSendVersion; | ||||
} | } | ||||
int TransportDeserializer::readHeader(const Config &config, const char *pch, | int V1TransportDeserializer::readHeader(const Config &config, const char *pch, | ||||
uint32_t nBytes) { | uint32_t nBytes) { | ||||
// copy data to temporary parsing buffer | // copy data to temporary parsing buffer | ||||
uint32_t nRemaining = 24 - nHdrPos; | uint32_t nRemaining = 24 - nHdrPos; | ||||
uint32_t nCopy = std::min(nRemaining, nBytes); | uint32_t nCopy = std::min(nRemaining, nBytes); | ||||
memcpy(&hdrbuf[nHdrPos], pch, nCopy); | memcpy(&hdrbuf[nHdrPos], pch, nCopy); | ||||
nHdrPos += nCopy; | nHdrPos += nCopy; | ||||
// if header incomplete, exit | // if header incomplete, exit | ||||
Show All 15 Lines | int V1TransportDeserializer::readHeader(const Config &config, const char *pch, | ||||
} | } | ||||
// switch state to reading message data | // switch state to reading message data | ||||
in_data = true; | in_data = true; | ||||
return nCopy; | return nCopy; | ||||
} | } | ||||
int TransportDeserializer::readData(const char *pch, uint32_t nBytes) { | int V1TransportDeserializer::readData(const char *pch, uint32_t nBytes) { | ||||
unsigned int nRemaining = hdr.nMessageSize - nDataPos; | unsigned int nRemaining = hdr.nMessageSize - nDataPos; | ||||
unsigned int nCopy = std::min(nRemaining, nBytes); | unsigned int nCopy = std::min(nRemaining, nBytes); | ||||
if (vRecv.size() < nDataPos + nCopy) { | if (vRecv.size() < nDataPos + nCopy) { | ||||
// Allocate up to 256 KiB ahead, but never more than the total message | // Allocate up to 256 KiB ahead, but never more than the total message | ||||
// size. | // size. | ||||
vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024)); | vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024)); | ||||
} | } | ||||
hasher.Write((const uint8_t *)pch, nCopy); | hasher.Write((const uint8_t *)pch, nCopy); | ||||
memcpy(&vRecv[nDataPos], pch, nCopy); | memcpy(&vRecv[nDataPos], pch, nCopy); | ||||
nDataPos += nCopy; | nDataPos += nCopy; | ||||
return nCopy; | return nCopy; | ||||
} | } | ||||
const uint256 &TransportDeserializer::GetMessageHash() const { | const uint256 &V1TransportDeserializer::GetMessageHash() const { | ||||
assert(complete()); | assert(Complete()); | ||||
if (data_hash.IsNull()) { | if (data_hash.IsNull()) { | ||||
hasher.Finalize(data_hash.begin()); | hasher.Finalize(data_hash.begin()); | ||||
} | } | ||||
return data_hash; | return data_hash; | ||||
} | } | ||||
CNetMessage TransportDeserializer::GetMessage(const Config &config, | CNetMessage V1TransportDeserializer::GetMessage(const Config &config, | ||||
int64_t time) { | int64_t time) { | ||||
// decompose a single CNetMessage from the TransportDeserializer | // decompose a single CNetMessage from the TransportDeserializer | ||||
CNetMessage msg(std::move(vRecv)); | CNetMessage msg(std::move(vRecv)); | ||||
// store state about valid header, netmagic and checksum | // store state about valid header, netmagic and checksum | ||||
msg.m_valid_header = hdr.IsValid(config); | msg.m_valid_header = hdr.IsValid(config); | ||||
// FIXME Split CheckHeaderMagicAndCommand() into CheckHeaderMagic() and | // FIXME Split CheckHeaderMagicAndCommand() into CheckHeaderMagic() and | ||||
// CheckCommand() to prevent the net magic check code duplication. | // CheckCommand() to prevent the net magic check code duplication. | ||||
msg.m_valid_netmagic = | msg.m_valid_netmagic = | ||||
▲ Show 20 Lines • Show All 2,208 Lines • ▼ Show 20 Lines | CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, | ||||
mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; | mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; | ||||
if (fLogIPs) { | if (fLogIPs) { | ||||
LogPrint(BCLog::NET, "Added connection to %s peer=%d\n", addrName, id); | LogPrint(BCLog::NET, "Added connection to %s peer=%d\n", addrName, id); | ||||
} else { | } else { | ||||
LogPrint(BCLog::NET, "Added connection peer=%d\n", id); | LogPrint(BCLog::NET, "Added connection peer=%d\n", id); | ||||
} | } | ||||
m_deserializer = std::make_unique<TransportDeserializer>( | m_deserializer = std::make_unique<V1TransportDeserializer>( | ||||
TransportDeserializer(GetConfig().GetChainParams().NetMagic(), | V1TransportDeserializer(GetConfig().GetChainParams().NetMagic(), | ||||
SER_NETWORK, INIT_PROTO_VERSION)); | SER_NETWORK, INIT_PROTO_VERSION)); | ||||
} | } | ||||
CNode::~CNode() { | CNode::~CNode() { | ||||
CloseSocket(hSocket); | CloseSocket(hSocket); | ||||
} | } | ||||
bool CConnman::NodeFullyConnected(const CNode *pnode) { | bool CConnman::NodeFullyConnected(const CNode *pnode) { | ||||
return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect; | return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect; | ||||
▲ Show 20 Lines • Show All 134 Lines • Show Last 20 Lines |