aboutsummaryrefslogtreecommitdiff
path: root/src/net.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/net.h')
-rw-r--r--src/net.h267
1 files changed, 68 insertions, 199 deletions
diff --git a/src/net.h b/src/net.h
index 58b492e592..25d9bbc02b 100644
--- a/src/net.h
+++ b/src/net.h
@@ -136,6 +136,33 @@ public:
bool ForNode(NodeId id, std::function<bool(CNode* pnode)> func);
+ template <typename... Args>
+ void PushMessageWithVersionAndFlag(CNode* pnode, int nVersion, int flag, const std::string& sCommand, Args&&... args)
+ {
+ auto msg(BeginMessage(pnode, nVersion, flag, sCommand));
+ ::SerializeMany(msg, std::forward<Args>(args)...);
+ EndMessage(msg);
+ PushMessage(pnode, msg, sCommand);
+ }
+
+ template <typename... Args>
+ void PushMessageWithFlag(CNode* pnode, int flag, const std::string& sCommand, Args&&... args)
+ {
+ PushMessageWithVersionAndFlag(pnode, 0, flag, sCommand, std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ void PushMessageWithVersion(CNode* pnode, int nVersion, const std::string& sCommand, Args&&... args)
+ {
+ PushMessageWithVersionAndFlag(pnode, nVersion, 0, sCommand, std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ void PushMessage(CNode* pnode, const std::string& sCommand, Args&&... args)
+ {
+ PushMessageWithVersionAndFlag(pnode, 0, 0, sCommand, std::forward<Args>(args)...);
+ }
+
template<typename Callable>
bool ForEachNodeContinueIf(Callable&& func)
{
@@ -345,6 +372,10 @@ private:
unsigned int GetReceiveFloodSize() const;
+ CDataStream BeginMessage(CNode* node, int nVersion, int flags, const std::string& sCommand);
+ void PushMessage(CNode* pnode, CDataStream& strm, const std::string& sCommand);
+ void EndMessage(CDataStream& strm);
+
// Network stats
void RecordBytesRecv(uint64_t bytes);
void RecordBytesSent(uint64_t bytes);
@@ -428,7 +459,7 @@ struct CNodeSignals
{
boost::signals2::signal<bool (CNode*, CConnman&), CombinerAll> ProcessMessages;
boost::signals2::signal<bool (CNode*, CConnman&), CombinerAll> SendMessages;
- boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
+ boost::signals2::signal<void (CNode*, CConnman&)> InitializeNode;
boost::signals2::signal<void (NodeId, bool&)> FinalizeNode;
};
@@ -512,6 +543,9 @@ public:
class CNetMessage {
+private:
+ mutable CHash256 hasher;
+ mutable uint256 data_hash;
public:
bool in_data; // parsing header (false) or data (true)
@@ -539,6 +573,8 @@ public:
return (hdr.nMessageSize == nDataPos);
}
+ const uint256& GetMessageHash() const;
+
void SetVersion(int nVersionIn)
{
hdrbuf.SetVersion(nVersionIn);
@@ -553,15 +589,14 @@ public:
/** Information about a peer */
class CNode
{
+ friend class CConnman;
public:
// socket
ServiceFlags nServices;
ServiceFlags nServicesExpected;
SOCKET hSocket;
- CDataStream ssSend;
size_t nSendSize; // total size of all vSendMsg entries
size_t nSendOffset; // offset inside the first vSendMsg already sent
- uint64_t nOptimisticBytesWritten;
uint64_t nSendBytes;
std::deque<CSerializeData> vSendMsg;
CCriticalSection cs_vSend;
@@ -589,7 +624,7 @@ public:
bool fFeeler; // If true this node is being used as a short lived feeler.
bool fOneShot;
bool fClient;
- bool fInbound;
+ const bool fInbound;
bool fNetworkNode;
bool fSuccessfullyConnected;
bool fDisconnect;
@@ -603,7 +638,7 @@ public:
CCriticalSection cs_filter;
CBloomFilter* pfilter;
int nRefCount;
- NodeId id;
+ const NodeId id;
const uint64_t nKeyedNetGroup;
protected:
@@ -611,9 +646,6 @@ protected:
mapMsgCmdSize mapSendBytesPerMsgCmd;
mapMsgCmdSize mapRecvBytesPerMsgCmd;
- // Basic fuzz-testing
- void Fuzz(int nChance); // modifies ssSend
-
public:
uint256 hashContinue;
int nStartingHeight;
@@ -669,7 +701,7 @@ public:
CAmount lastSentFeeFilter;
int64_t nextSendTimeFeeFilter;
- CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, const std::string &addrNameIn = "", bool fInboundIn = false);
+ CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const std::string &addrNameIn = "", bool fInboundIn = false);
~CNode();
private:
@@ -677,10 +709,11 @@ private:
void operator=(const CNode&);
- uint64_t nLocalHostNonce;
+ const uint64_t nLocalHostNonce;
// Services offered to this peer
- ServiceFlags nLocalServices;
- int nMyStartingHeight;
+ const ServiceFlags nLocalServices;
+ const int nMyStartingHeight;
+ int nSendVersion;
public:
NodeId GetId() const {
@@ -691,6 +724,10 @@ public:
return nLocalHostNonce;
}
+ int GetMyStartingHeight() const {
+ return nMyStartingHeight;
+ }
+
int GetRefCount()
{
assert(nRefCount >= 0);
@@ -716,6 +753,25 @@ public:
BOOST_FOREACH(CNetMessage &msg, vRecvMsg)
msg.SetVersion(nVersionIn);
}
+ void SetSendVersion(int nVersionIn)
+ {
+ // Send version may only be changed in the version message, and
+ // only one version message is allowed per session. We can therefore
+ // treat this value as const and even atomic as long as it's only used
+ // once the handshake is complete. Any attempt to set this twice is an
+ // error.
+ assert(nSendVersion == 0);
+ nSendVersion = nVersionIn;
+ }
+
+ int GetSendVersion() const
+ {
+ // The send version should always be explicitly set to
+ // INIT_PROTO_VERSION rather than using this value until the handshake
+ // is complete. See PushMessageWithVersion().
+ assert(nSendVersion != 0);
+ return nSendVersion;
+ }
CNode* AddRef()
{
@@ -778,193 +834,6 @@ public:
void AskFor(const CInv& inv);
- // TODO: Document the postcondition of this function. Is cs_vSend locked?
- void BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend);
-
- // TODO: Document the precondition of this function. Is cs_vSend locked?
- void AbortMessage() UNLOCK_FUNCTION(cs_vSend);
-
- // TODO: Document the precondition of this function. Is cs_vSend locked?
- void EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend);
-
- void PushVersion();
-
-
- void PushMessage(const char* pszCommand)
- {
- try
- {
- BeginMessage(pszCommand);
- EndMessage(pszCommand);
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1>
- void PushMessage(const char* pszCommand, const T1& a1)
- {
- try
- {
- BeginMessage(pszCommand);
- ssSend << a1;
- EndMessage(pszCommand);
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- /** Send a message containing a1, serialized with flag flag. */
- template<typename T1>
- void PushMessageWithFlag(int flag, const char* pszCommand, const T1& a1)
- {
- try
- {
- BeginMessage(pszCommand);
- WithOrVersion(&ssSend, flag) << a1;
- EndMessage(pszCommand);
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
- {
- try
- {
- BeginMessage(pszCommand);
- ssSend << a1 << a2;
- EndMessage(pszCommand);
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2, typename T3>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
- {
- try
- {
- BeginMessage(pszCommand);
- ssSend << a1 << a2 << a3;
- EndMessage(pszCommand);
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2, typename T3, typename T4>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
- {
- try
- {
- BeginMessage(pszCommand);
- ssSend << a1 << a2 << a3 << a4;
- EndMessage(pszCommand);
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
- {
- try
- {
- BeginMessage(pszCommand);
- ssSend << a1 << a2 << a3 << a4 << a5;
- EndMessage(pszCommand);
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
- {
- try
- {
- BeginMessage(pszCommand);
- ssSend << a1 << a2 << a3 << a4 << a5 << a6;
- EndMessage(pszCommand);
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7)
- {
- try
- {
- BeginMessage(pszCommand);
- ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
- EndMessage(pszCommand);
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8)
- {
- try
- {
- BeginMessage(pszCommand);
- ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
- EndMessage(pszCommand);
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
- template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
- void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9)
- {
- try
- {
- BeginMessage(pszCommand);
- ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
- EndMessage(pszCommand);
- }
- catch (...)
- {
- AbortMessage();
- throw;
- }
- }
-
void CloseSocketDisconnect();
void copyStats(CNodeStats &stats);