aboutsummaryrefslogtreecommitdiff
path: root/src/net.h
diff options
context:
space:
mode:
authorCory Fields <cory-nospam-@coryfields.com>2016-09-12 20:00:33 -0400
committerPieter Wuille <pieter.wuille@gmail.com>2016-11-03 13:32:09 -0700
commit3e32cd09f643bf7d4344d3bb2e1136f186f3d109 (patch)
tree315c62f9fa5df102dce6f211083bfa682c3794be /src/net.h
parentb98c14c4e362a8e59d7a3b021651a19ea61b29dd (diff)
downloadbitcoin-3e32cd09f643bf7d4344d3bb2e1136f186f3d109.tar.xz
connman is in charge of pushing messages
The changes here are dense and subtle, but hopefully all is more explicit than before. - CConnman is now in charge of sending data rather than the nodes themselves. This is necessary because many decisions need to be made with all nodes in mind, and a model that requires the nodes calling up to their manager quickly turns to spaghetti. - The per-node-serializer (ssSend) has been replaced with a (quasi-)const send-version. Since the send version for serialization can only change once per connection, we now explicitly tag messages with INIT_PROTO_VERSION if they are sent before the handshake. With this done, there's no need to lock for access to nSendVersion. Also, a new stream is used for each message, so there's no need to lock during the serialization process. - This takes care of accounting for optimistic sends, so the nOptimisticBytesWritten hack can be removed. - -dropmessagestest and -fuzzmessagestest have not been preserved, as I suspect they haven't been used in years.
Diffstat (limited to 'src/net.h')
-rw-r--r--src/net.h58
1 files changed, 55 insertions, 3 deletions
diff --git a/src/net.h b/src/net.h
index bfce516237..c33de9824b 100644
--- a/src/net.h
+++ b/src/net.h
@@ -136,6 +136,36 @@ 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, msg.nType, msg.nVersion, 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)...);
+ }
+
+ void PushVersion(CNode* pnode, int64_t nTime);
+
+
template<typename Callable>
bool ForEachNodeContinueIf(Callable&& func)
{
@@ -345,6 +375,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);
@@ -553,6 +587,7 @@ public:
/** Information about a peer */
class CNode
{
+ friend class CConnman;
public:
// socket
ServiceFlags nServices;
@@ -681,6 +716,7 @@ private:
// Services offered to this peer
const ServiceFlags nLocalServices;
const int nMyStartingHeight;
+ int nSendVersion;
public:
NodeId GetId() const {
@@ -716,6 +752,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()
{
@@ -787,9 +842,6 @@ public:
// 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