upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/net.h16
-rw-r--r--src/selftest.cpp37
2 files changed, 38 insertions, 15 deletions
diff --git a/src/net.h b/src/net.h
index 8b0245a..3c8c409 100644
--- a/src/net.h
+++ b/src/net.h
@@ -89,10 +89,9 @@ static const int BTF_HANDSHAKE_GRACE_SECS = 60;
89 89
90// A serialized object cannot be larger than MAX_SIZE, so no valid network 90// A serialized object cannot be larger than MAX_SIZE, so no valid network
91// message needs the old 256 MB header allowance. Keep the wire cap aligned with 91// message needs the old 256 MB header allowance. Keep the wire cap aligned with
92// what the deserializer can accept and bound how long one peer may sit on a 92// what the deserializer can accept. How long a peer may sit on a partial
93// partial payload after a complete header has arrived. 93// payload after a complete header has arrived is BTF_MSG_WAIT_MAX_SECS, below.
94static const unsigned int MAX_PROTOCOL_MESSAGE_SIZE = MAX_SIZE; 94static const unsigned int MAX_PROTOCOL_MESSAGE_SIZE = MAX_SIZE;
95static const int BTF_INCOMPLETE_MESSAGE_TIMEOUT_SECS = 2 * 60;
96 95
97// Ceiling on simultaneous connections. 96// Ceiling on simultaneous connections.
98// 97//
@@ -656,9 +655,6 @@ public:
656 int64 nLastSend; 655 int64 nLastSend;
657 int64 nLastRecv; 656 int64 nLastRecv;
658 int64 nLastSendEmpty; 657 int64 nLastSendEmpty;
659 int64 nIncompleteMessageStart;
660 unsigned int nIncompleteMessageSize;
661 string strIncompleteMessageCommand;
662 string strBtfAddr; 658 string strBtfAddr;
663 string strBtfMeeting; 659 string strBtfMeeting;
664 660
@@ -699,11 +695,13 @@ public:
699 nLastSend = 0; 695 nLastSend = 0;
700 nLastRecv = 0; 696 nLastRecv = 0;
701 nLastSendEmpty = GetTime(); 697 nLastSendEmpty = GetTime();
702 nIncompleteMessageStart = 0;
703 nIncompleteMessageSize = 0;
704 strIncompleteMessageCommand.clear();
705 strBtfAddr.clear(); 698 strBtfAddr.clear();
706 strBtfMeeting.clear(); 699 strBtfMeeting.clear();
700 // Not waiting on anything yet. Left indeterminate, the first partial
701 // message this peer sends is measured against whatever was in this
702 // memory, and ProcessMessages drops it as unreadable on first contact.
703 nMsgWaitSince = 0;
704 nMsgWaitSize = 0;
707 nStartingHeight = -1; 705 nStartingHeight = -1;
708 706
709 // Push a version message 707 // Push a version message
diff --git a/src/selftest.cpp b/src/selftest.cpp
index ff0289b..d12c96b 100644
--- a/src/selftest.cpp
+++ b/src/selftest.cpp
@@ -1105,6 +1105,13 @@ static int RunNetMessageSelfTest()
1105 int nFail = 0; 1105 int nFail = 0;
1106 try 1106 try
1107 { 1107 {
1108 // A peer that has not yet been kept waiting must not look like one that
1109 // has been waiting since the epoch. This is the whole bug: the stall
1110 // clock lives in CNode, so only the constructor can start it at zero.
1111 CNode opened(INVALID_SOCKET, CAddress("127.0.0.1"));
1112 nFail += Check(opened.nMsgWaitSince == 0 && opened.nMsgWaitSize == 0,
1113 "a new peer starts with its stall clock stopped") ? 0 : 1;
1114
1108 CNode complete(INVALID_SOCKET, CAddress("127.0.0.1")); 1115 CNode complete(INVALID_SOCKET, CAddress("127.0.0.1"));
1109 complete.nVersion = VERSION; 1116 complete.nVersion = VERSION;
1110 complete.vRecv << CMessageHeader("ping", 0); 1117 complete.vRecv << CMessageHeader("ping", 0);
@@ -1119,20 +1126,38 @@ static int RunNetMessageSelfTest()
1119 nFail += Check(ProcessMessages(&partial), "an incomplete message returns cleanly") ? 0 : 1; 1126 nFail += Check(ProcessMessages(&partial), "an incomplete message returns cleanly") ? 0 : 1;
1120 nFail += Check(partial.vRecv.size() == nPartialBefore, 1127 nFail += Check(partial.vRecv.size() == nPartialBefore,
1121 "an incomplete message keeps one header in the buffer") ? 0 : 1; 1128 "an incomplete message keeps one header in the buffer") ? 0 : 1;
1122 nFail += Check(partial.nIncompleteMessageStart != 0, 1129 nFail += Check(partial.nMsgWaitSince != 0,
1123 "an incomplete message starts a timeout clock") ? 0 : 1; 1130 "an incomplete message starts the stall clock") ? 0 : 1;
1131 nFail += Check(partial.nMsgWaitSize == 0,
1132 "the stall clock records how much payload had arrived") ? 0 : 1;
1124 nFail += Check(!partial.fDisconnect, 1133 nFail += Check(!partial.fDisconnect,
1125 "a fresh incomplete message does not disconnect immediately") ? 0 : 1; 1134 "a fresh incomplete message does not disconnect immediately") ? 0 : 1;
1126 1135
1136 // Still arriving, just slowly: more payload is here than when the clock
1137 // was started, so the clock restarts however old it was. Timing the
1138 // wait instead of the stall would drop this peer.
1139 CNode slow(INVALID_SOCKET, CAddress("127.0.0.1"));
1140 slow.nVersion = VERSION;
1141 slow.vRecv << CMessageHeader("block", 100);
1142 slow.vRecv.insert(slow.vRecv.end(), 50, '\0');
1143 slow.nMsgWaitSince = GetTime() - BTF_MSG_WAIT_MAX_SECS - 1;
1144 slow.nMsgWaitSize = 10;
1145 ProcessMessages(&slow);
1146 nFail += Check(!slow.fDisconnect,
1147 "a peer still sending payload is not dropped") ? 0 : 1;
1148 nFail += Check(slow.nMsgWaitSize == 50,
1149 "progress restarts the stall clock") ? 0 : 1;
1150
1151 // Nothing more has arrived since the clock started, and the clock is
1152 // older than the limit.
1127 CNode stale(INVALID_SOCKET, CAddress("127.0.0.1")); 1153 CNode stale(INVALID_SOCKET, CAddress("127.0.0.1"));
1128 stale.nVersion = VERSION; 1154 stale.nVersion = VERSION;
1129 stale.vRecv << CMessageHeader("block", 100); 1155 stale.vRecv << CMessageHeader("block", 100);
1130 stale.nIncompleteMessageStart = GetTime() - BTF_INCOMPLETE_MESSAGE_TIMEOUT_SECS - 1; 1156 stale.nMsgWaitSince = GetTime() - BTF_MSG_WAIT_MAX_SECS - 1;
1131 stale.nIncompleteMessageSize = 100; 1157 stale.nMsgWaitSize = 0;
1132 stale.strIncompleteMessageCommand = "block";
1133 ProcessMessages(&stale); 1158 ProcessMessages(&stale);
1134 nFail += Check(stale.fDisconnect, 1159 nFail += Check(stale.fDisconnect,
1135 "a stale incomplete message disconnects the peer") ? 0 : 1; 1160 "a stalled incomplete message disconnects the peer") ? 0 : 1;
1136 1161
1137 CNode oversized(INVALID_SOCKET, CAddress("127.0.0.1")); 1162 CNode oversized(INVALID_SOCKET, CAddress("127.0.0.1"));
1138 oversized.nVersion = VERSION; 1163 oversized.nVersion = VERSION;