Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 481 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static void UpdatePreferredDownload(const CNode &node, CNodeState *state) | static void UpdatePreferredDownload(const CNode &node, CNodeState *state) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | ||||
nPreferredDownload -= state->fPreferredDownload; | nPreferredDownload -= state->fPreferredDownload; | ||||
// Whether this node should be marked as a preferred download node. | // Whether this node should be marked as a preferred download node. | ||||
state->fPreferredDownload = | state->fPreferredDownload = | ||||
(!node.fInbound || node.HasPermission(PF_NOBAN)) && | (!node.IsInboundConn() || node.HasPermission(PF_NOBAN)) && | ||||
!node.IsAddrFetchConn() && !node.fClient; | !node.IsAddrFetchConn() && !node.fClient; | ||||
nPreferredDownload += state->fPreferredDownload; | nPreferredDownload += state->fPreferredDownload; | ||||
} | } | ||||
static void PushNodeVersion(const Config &config, CNode &pnode, | static void PushNodeVersion(const Config &config, CNode &pnode, | ||||
CConnman &connman, int64_t nTime) { | CConnman &connman, int64_t nTime) { | ||||
// Note that pnode.GetLocalServices() is a reflection of the local | // Note that pnode.GetLocalServices() is a reflection of the local | ||||
▲ Show 20 Lines • Show All 431 Lines • ▼ Show 20 Lines | void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds) { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
CNodeState *state = State(node); | CNodeState *state = State(node); | ||||
if (state) { | if (state) { | ||||
state->m_last_block_announcement = time_in_seconds; | state->m_last_block_announcement = time_in_seconds; | ||||
} | } | ||||
} | } | ||||
static bool IsOutboundDisconnectionCandidate(const CNode &node) { | static bool IsOutboundDisconnectionCandidate(const CNode &node) { | ||||
return !(node.fInbound || node.IsManualConn() || node.IsFeelerConn() || | return !(node.IsInboundConn() || node.IsManualConn() || | ||||
node.IsAddrFetchConn()); | node.IsFeelerConn() || node.IsAddrFetchConn()); | ||||
} | } | ||||
void PeerLogicValidation::InitializeNode(const Config &config, CNode *pnode) { | void PeerLogicValidation::InitializeNode(const Config &config, CNode *pnode) { | ||||
CAddress addr = pnode->addr; | CAddress addr = pnode->addr; | ||||
std::string addrName = pnode->GetAddrName(); | std::string addrName = pnode->GetAddrName(); | ||||
NodeId nodeid = pnode->GetId(); | NodeId nodeid = pnode->GetId(); | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
mapNodeState.emplace_hint( | mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, | ||||
mapNodeState.end(), std::piecewise_construct, | |||||
std::forward_as_tuple(nodeid), | std::forward_as_tuple(nodeid), | ||||
std::forward_as_tuple(addr, std::move(addrName), pnode->fInbound, | std::forward_as_tuple(addr, | ||||
std::move(addrName), | |||||
pnode->IsInboundConn(), | |||||
pnode->IsManualConn())); | pnode->IsManualConn())); | ||||
} | } | ||||
if (!pnode->fInbound) { | if (!pnode->IsInboundConn()) { | ||||
PushNodeVersion(config, *pnode, *connman, GetTime()); | PushNodeVersion(config, *pnode, *connman, GetTime()); | ||||
} | } | ||||
} | } | ||||
void PeerLogicValidation::FinalizeNode(const Config &config, NodeId nodeid, | void PeerLogicValidation::FinalizeNode(const Config &config, NodeId nodeid, | ||||
bool &fUpdateConnectionTime) { | bool &fUpdateConnectionTime) { | ||||
fUpdateConnectionTime = false; | fUpdateConnectionTime = false; | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
▲ Show 20 Lines • Show All 1,566 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::VERSION) { | ||||
int nSendVersion; | int nSendVersion; | ||||
std::string cleanSubVer; | std::string cleanSubVer; | ||||
int nStartingHeight = -1; | int nStartingHeight = -1; | ||||
bool fRelay = true; | bool fRelay = true; | ||||
vRecv >> nVersion >> nServiceInt >> nTime >> addrMe; | vRecv >> nVersion >> nServiceInt >> nTime >> addrMe; | ||||
nSendVersion = std::min(nVersion, PROTOCOL_VERSION); | nSendVersion = std::min(nVersion, PROTOCOL_VERSION); | ||||
nServices = ServiceFlags(nServiceInt); | nServices = ServiceFlags(nServiceInt); | ||||
if (!pfrom.fInbound) { | if (!pfrom.IsInboundConn()) { | ||||
connman.SetServices(pfrom.addr, nServices); | connman.SetServices(pfrom.addr, nServices); | ||||
} | } | ||||
if (!pfrom.fInbound && !pfrom.IsFeelerConn() && !pfrom.IsManualConn() && | if (!pfrom.IsInboundConn() && !pfrom.IsFeelerConn() && | ||||
!HasAllDesirableServiceFlags(nServices)) { | !pfrom.IsManualConn() && !HasAllDesirableServiceFlags(nServices)) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"peer=%d does not offer the expected services " | "peer=%d does not offer the expected services " | ||||
"(%08x offered, %08x expected); disconnecting\n", | "(%08x offered, %08x expected); disconnecting\n", | ||||
pfrom.GetId(), nServices, | pfrom.GetId(), nServices, | ||||
GetDesirableServiceFlags(nServices)); | GetDesirableServiceFlags(nServices)); | ||||
pfrom.fDisconnect = true; | pfrom.fDisconnect = true; | ||||
return false; | return false; | ||||
} | } | ||||
Show All 17 Lines | if (msg_type == NetMsgType::VERSION) { | ||||
} | } | ||||
if (!vRecv.empty()) { | if (!vRecv.empty()) { | ||||
vRecv >> nStartingHeight; | vRecv >> nStartingHeight; | ||||
} | } | ||||
if (!vRecv.empty()) { | if (!vRecv.empty()) { | ||||
vRecv >> fRelay; | vRecv >> fRelay; | ||||
} | } | ||||
// Disconnect if we connected to ourself | // Disconnect if we connected to ourself | ||||
if (pfrom.fInbound && !connman.CheckIncomingNonce(nNonce)) { | if (pfrom.IsInboundConn() && !connman.CheckIncomingNonce(nNonce)) { | ||||
LogPrintf("connected to self at %s, disconnecting\n", | LogPrintf("connected to self at %s, disconnecting\n", | ||||
pfrom.addr.ToString()); | pfrom.addr.ToString()); | ||||
pfrom.fDisconnect = true; | pfrom.fDisconnect = true; | ||||
return true; | return true; | ||||
} | } | ||||
if (pfrom.fInbound && addrMe.IsRoutable()) { | if (pfrom.IsInboundConn() && addrMe.IsRoutable()) { | ||||
SeenLocal(addrMe); | SeenLocal(addrMe); | ||||
} | } | ||||
// Be shy and don't send version until we hear | // Be shy and don't send version until we hear | ||||
if (pfrom.fInbound) { | if (pfrom.IsInboundConn()) { | ||||
PushNodeVersion(config, pfrom, connman, GetAdjustedTime()); | PushNodeVersion(config, pfrom, connman, GetAdjustedTime()); | ||||
} | } | ||||
connman.PushMessage( | connman.PushMessage( | ||||
&pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERACK)); | &pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERACK)); | ||||
pfrom.nServices = nServices; | pfrom.nServices = nServices; | ||||
pfrom.SetAddrLocal(addrMe); | pfrom.SetAddrLocal(addrMe); | ||||
Show All 24 Lines | if (msg_type == NetMsgType::VERSION) { | ||||
pfrom.nVersion = nVersion; | pfrom.nVersion = nVersion; | ||||
// Potentially mark this peer as a preferred download peer. | // Potentially mark this peer as a preferred download peer. | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
UpdatePreferredDownload(pfrom, State(pfrom.GetId())); | UpdatePreferredDownload(pfrom, State(pfrom.GetId())); | ||||
} | } | ||||
if (!pfrom.fInbound && pfrom.IsAddrRelayPeer()) { | if (!pfrom.IsInboundConn() && pfrom.IsAddrRelayPeer()) { | ||||
// Advertise our address | // Advertise our address | ||||
if (fListen && !::ChainstateActive().IsInitialBlockDownload()) { | if (fListen && !::ChainstateActive().IsInitialBlockDownload()) { | ||||
CAddress addr = | CAddress addr = | ||||
GetLocalAddress(&pfrom.addr, pfrom.GetLocalServices()); | GetLocalAddress(&pfrom.addr, pfrom.GetLocalServices()); | ||||
FastRandomContext insecure_rand; | FastRandomContext insecure_rand; | ||||
if (addr.IsRoutable()) { | if (addr.IsRoutable()) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"ProcessMessages: advertising address %s\n", | "ProcessMessages: advertising address %s\n", | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | bool ProcessMessage(const Config &config, CNode &pfrom, | ||||
} | } | ||||
// At this point, the outgoing message serialization version can't change. | // At this point, the outgoing message serialization version can't change. | ||||
const CNetMsgMaker msgMaker(pfrom.GetSendVersion()); | const CNetMsgMaker msgMaker(pfrom.GetSendVersion()); | ||||
if (msg_type == NetMsgType::VERACK) { | if (msg_type == NetMsgType::VERACK) { | ||||
pfrom.SetRecvVersion(std::min(pfrom.nVersion.load(), PROTOCOL_VERSION)); | pfrom.SetRecvVersion(std::min(pfrom.nVersion.load(), PROTOCOL_VERSION)); | ||||
if (!pfrom.fInbound) { | if (!pfrom.IsInboundConn()) { | ||||
// Mark this node as currently connected, so we update its timestamp | // Mark this node as currently connected, so we update its timestamp | ||||
// later. | // later. | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
State(pfrom.GetId())->fCurrentlyConnected = true; | State(pfrom.GetId())->fCurrentlyConnected = true; | ||||
LogPrintf( | LogPrintf( | ||||
"New outbound peer connected: version: %d, blocks=%d, " | "New outbound peer connected: version: %d, blocks=%d, " | ||||
"peer=%d%s (%s)\n", | "peer=%d%s (%s)\n", | ||||
pfrom.nVersion.load(), pfrom.nStartingHeight, pfrom.GetId(), | pfrom.nVersion.load(), pfrom.nStartingHeight, pfrom.GetId(), | ||||
▲ Show 20 Lines • Show All 1,207 Lines • ▼ Show 20 Lines | |||||
if (msg_type == NetMsgType::GETADDR) { | if (msg_type == NetMsgType::GETADDR) { | ||||
// This asymmetric behavior for inbound and outbound connections was | // This asymmetric behavior for inbound and outbound connections was | ||||
// introduced to prevent a fingerprinting attack: an attacker can send | // introduced to prevent a fingerprinting attack: an attacker can send | ||||
// specific fake addresses to users' AddrMan and later request them by | // specific fake addresses to users' AddrMan and later request them by | ||||
// sending getaddr messages. Making nodes which are behind NAT and can | // sending getaddr messages. Making nodes which are behind NAT and can | ||||
// only make outgoing connections ignore the getaddr message mitigates | // only make outgoing connections ignore the getaddr message mitigates | ||||
// the attack. | // the attack. | ||||
if (!pfrom.fInbound) { | if (!pfrom.IsInboundConn()) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"Ignoring \"getaddr\" from outbound connection. peer=%d\n", | "Ignoring \"getaddr\" from outbound connection. peer=%d\n", | ||||
pfrom.GetId()); | pfrom.GetId()); | ||||
return true; | return true; | ||||
} | } | ||||
if (!pfrom.IsAddrRelayPeer()) { | if (!pfrom.IsAddrRelayPeer()) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"Ignoring \"getaddr\" from block-relay-only connection. " | "Ignoring \"getaddr\" from block-relay-only connection. " | ||||
▲ Show 20 Lines • Show All 954 Lines • ▼ Show 20 Lines | std::vector<CInv> vInv; | ||||
pto->vInventoryBlockToSend.clear(); | pto->vInventoryBlockToSend.clear(); | ||||
if (pto->m_tx_relay != nullptr) { | if (pto->m_tx_relay != nullptr) { | ||||
LOCK(pto->m_tx_relay->cs_tx_inventory); | LOCK(pto->m_tx_relay->cs_tx_inventory); | ||||
// Check whether periodic sends should happen | // Check whether periodic sends should happen | ||||
bool fSendTrickle = pto->HasPermission(PF_NOBAN); | bool fSendTrickle = pto->HasPermission(PF_NOBAN); | ||||
if (pto->m_tx_relay->nNextInvSend < current_time) { | if (pto->m_tx_relay->nNextInvSend < current_time) { | ||||
fSendTrickle = true; | fSendTrickle = true; | ||||
if (pto->fInbound) { | if (pto->IsInboundConn()) { | ||||
pto->m_tx_relay->nNextInvSend = std::chrono::microseconds{ | pto->m_tx_relay->nNextInvSend = std::chrono::microseconds{ | ||||
connman->PoissonNextSendInbound( | connman->PoissonNextSendInbound( | ||||
nNow, INVENTORY_BROADCAST_INTERVAL)}; | nNow, INVENTORY_BROADCAST_INTERVAL)}; | ||||
} else { | } else { | ||||
// Skip delay for outbound peers, as there is less | // Skip delay for outbound peers, as there is less | ||||
// privacy concern for them. | // privacy concern for them. | ||||
pto->m_tx_relay->nNextInvSend = current_time; | pto->m_tx_relay->nNextInvSend = current_time; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 381 Lines • Show Last 20 Lines |