diff options
Diffstat (limited to 'src/net.h')
| -rw-r--r-- | src/net.h | 150 |
1 files changed, 117 insertions, 33 deletions
| @@ -12,7 +12,13 @@ class CBlockIndex; | |||
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | static const unsigned short DEFAULT_PORT = htons(8433); | 15 | // Held in host byte order, unlike the DEFAULT_PORT constant these replace, |
| 16 | // which was htons(8433). Nothing is lost: net.cpp's GetDefaultPort() applies | ||
| 17 | // htons() itself and is what every caller now uses, so the value that reaches | ||
| 18 | // a sockaddr is byte-for-byte what it was. Mainnet stays on 8433. | ||
| 19 | static const unsigned short MAINNET_PORT = 8433; | ||
| 20 | static const unsigned short TESTNET_PORT = 18433; | ||
| 21 | static const unsigned int PUBLISH_HOPS = 5; | ||
| 16 | enum | 22 | enum |
| 17 | { | 23 | { |
| 18 | NODE_NETWORK = (1 << 0), | 24 | NODE_NETWORK = (1 << 0), |
| @@ -23,13 +29,24 @@ enum | |||
| 23 | 29 | ||
| 24 | 30 | ||
| 25 | 31 | ||
| 32 | // Defined in main.cpp. True while this node is tracking the tip rather than | ||
| 33 | // still catching up, measured off the age of our own best block -- see there | ||
| 34 | // for why that and not a peer-reported height. Declared here because net.h is | ||
| 35 | // parsed before main.h and CNode::AskFor needs it. | ||
| 36 | bool IsBlockFetchNearTip(); | ||
| 37 | |||
| 26 | bool GetMyExternalIP(unsigned int& ipRet); | 38 | bool GetMyExternalIP(unsigned int& ipRet); |
| 39 | bool IsTestNet(); | ||
| 40 | unsigned short GetDefaultPort(); | ||
| 41 | void SelectNetworkParams(bool fTestNetIn); | ||
| 27 | CNode* ConnectNodeBtf(const string& strBtfAddr); | 42 | CNode* ConnectNodeBtf(const string& strBtfAddr); |
| 28 | CNode* ConnectNodeBtfResolved(const string& strBtfAddr, const string& strMeeting, | 43 | CNode* ConnectNodeBtfResolved(const string& strBtfAddr, const string& strMeeting, |
| 29 | const unsigned char enc_pub[32]); | 44 | const string& strOnion, const unsigned char enc_pub[32], |
| 45 | const string& strDesc=string()); | ||
| 30 | void ThreadBtfAccept(void* parg); | 46 | void ThreadBtfAccept(void* parg); |
| 31 | void ThreadBtfConnect(void* parg); | 47 | void ThreadBtfConnect(void* parg); |
| 32 | extern string strBtfConnect; | 48 | extern string strBtfConnect; |
| 49 | extern bool fBtfOnionOnly; | ||
| 33 | // Bootstrap seeds added at runtime with /btfseed=ADDRESS:ENCHEX (repeatable). | 50 | // Bootstrap seeds added at runtime with /btfseed=ADDRESS:ENCHEX (repeatable). |
| 34 | // The compiled-in list lives in net.cpp; these are appended to it. | 51 | // The compiled-in list lives in net.cpp; these are appended to it. |
| 35 | extern std::vector<std::pair<std::string, std::string> > vBtfExtraSeeds; | 52 | extern std::vector<std::pair<std::string, std::string> > vBtfExtraSeeds; |
| @@ -87,30 +104,52 @@ static const int BTF_RECV_TIMEOUT_SECS = 30 * 60; | |||
| 87 | static const int BTF_SEND_STALL_SECS = 10 * 60; | 104 | static const int BTF_SEND_STALL_SECS = 10 * 60; |
| 88 | static const int BTF_HANDSHAKE_GRACE_SECS = 60; | 105 | static const int BTF_HANDSHAKE_GRACE_SECS = 60; |
| 89 | 106 | ||
| 107 | // How long a requested block gets before it is asked for again, in seconds. | ||
| 108 | // Used twice: CNode::AskFor spaces the queued per-announcer block retries this | ||
| 109 | // far apart instead of the two minutes transactions get, and the failover | ||
| 110 | // sweep in main.cpp re-issues a getdata to a different peer once a sent | ||
| 111 | // request has gone unanswered this long. A block body is at most 1 MB and | ||
| 112 | // somebody demonstrably has it -- they announced it -- so on this timescale | ||
| 113 | // "not here yet" means "not coming from that peer", not "still in transit". | ||
| 114 | static const int BLOCK_FETCH_RETRY_SECS = 15; | ||
| 115 | |||
| 90 | // A serialized object cannot be larger than MAX_SIZE, so no valid network | 116 | // 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 | 117 | // 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 | 118 | // what the deserializer can accept. How long a peer may sit on a partial |
| 93 | // partial payload after a complete header has arrived. | 119 | // payload after a complete header has arrived is BTF_MSG_WAIT_MAX_SECS, below. |
| 94 | static const unsigned int MAX_PROTOCOL_MESSAGE_SIZE = MAX_SIZE; | 120 | static const unsigned int MAX_PROTOCOL_MESSAGE_SIZE = MAX_SIZE; |
| 95 | static const int BTF_INCOMPLETE_MESSAGE_TIMEOUT_SECS = 2 * 60; | ||
| 96 | 121 | ||
| 97 | // Ceiling on simultaneous connections. | 122 | // Ceiling on simultaneous connections. |
| 98 | // | 123 | // |
| 99 | // ThreadSocketHandler watches every peer through one select(), and select() | 124 | // ThreadSocketHandler watches every peer in one socket loop. This used to be a |
| 100 | // cannot watch more descriptors than FD_SETSIZE. On Windows FD_SET simply | 125 | // select() loop, which made FD_SETSIZE the real limit and silently starved |
| 101 | // stops adding once the set is full -- no error, no log -- so every socket | 126 | // sockets past that bitmap. It is now poll()/WSAPoll(), so the ceiling below is |
| 102 | // past the limit stays open and is never read again. Nothing capped vNodes, | 127 | // a deliberate resource bound rather than a descriptor-set accident. |
| 103 | // so a node accepted connections it had no way to service, and because new | ||
| 104 | // entries go on the end of vNodes it was always the newest connection that | ||
| 105 | // starved, including the ones dialed to fix connectivity. | ||
| 106 | // | 128 | // |
| 107 | // Measured on two nodes before this ceiling existed: 277 and 90 CNode objects | 129 | // Measured on two nodes before this ceiling existed: 277 and 90 CNode objects |
| 108 | // against 93 and 90 live sockets, and a status bar reporting hundreds of | 130 | // against 93 and 90 live sockets, and a status bar reporting hundreds of |
| 109 | // peers for a node that was really talking to thirty. | 131 | // peers for a node that was really talking to thirty. |
| 110 | // | 132 | // |
| 111 | // 125 is Bitcoin's number and sits far below FD_SETSIZE on both platforms. | 133 | // 125 is Bitcoin's number and remains a conservative public-node default. |
| 112 | static const unsigned int MAX_CONNECTIONS = 125; | 134 | static const unsigned int MAX_CONNECTIONS = 125; |
| 113 | 135 | ||
| 136 | // Cap inbound connections from any single address. Without it one source can | ||
| 137 | // hold every slot up to MAX_CONNECTIONS -- exactly what happened to the | ||
| 138 | // rendezvous relays, where a single IP parked hundreds of connections and | ||
| 139 | // starved real peers. A legitimate peer, even a relay talking to a relay, | ||
| 140 | // needs only a handful; 32 leaves generous room while denying any one address | ||
| 141 | // more than a quarter of the table. The firewall connlimit on the relays does | ||
| 142 | // the same thing a layer lower; this makes every build carry the defense. | ||
| 143 | // | ||
| 144 | // Loopback (127.0.0.0/8) is exempt in the accept path. A managed-Tor node | ||
| 145 | // receives every inbound onion peer over its local hidden-service listener, so | ||
| 146 | // they all appear as 127.0.0.1 -- capping loopback would cap onion peers as a | ||
| 147 | // group, which is exactly wrong for a network moving toward onion-only. The | ||
| 148 | // global MAX_CONNECTIONS still bounds the total; a per-onion-identity limit, | ||
| 149 | // applied once identity is known after accept(), is the right future tool for | ||
| 150 | // onion floods. | ||
| 151 | static const unsigned int MAX_CONNECTIONS_PER_IP = 32; | ||
| 152 | |||
| 114 | // A node marked for disconnect is normally held until its buffers drain, so | 153 | // A node marked for disconnect is normally held until its buffers drain, so |
| 115 | // a last message still goes out. But vSend cannot drain through a socket | 154 | // a last message still goes out. But vSend cannot drain through a socket |
| 116 | // whose far end is gone, and that made such a node immortal: it stayed in | 155 | // whose far end is gone, and that made such a node immortal: it stayed in |
| @@ -176,7 +215,7 @@ static const int BTF_BEHIND_WARN_INTERVAL_SECS = 5 * 60; | |||
| 176 | // | 215 | // |
| 177 | // These counters exist so it can. Cheap to keep, and they name the failures | 216 | // These counters exist so it can. Cheap to keep, and they name the failures |
| 178 | // that actually happened rather than the ones that sound impressive. | 217 | // that actually happened rather than the ones that sound impressive. |
| 179 | extern int nPeersWatched; // peers in the last select() set | 218 | extern int nPeersWatched; // peers in the last poll() set |
| 180 | extern int64 nBlocksReceived; // blocks handed to ProcessBlock | 219 | extern int64 nBlocksReceived; // blocks handed to ProcessBlock |
| 181 | extern int64 nBlocksWithoutParent; // ...of those, how many arrived orphaned | 220 | extern int64 nBlocksWithoutParent; // ...of those, how many arrived orphaned |
| 182 | 221 | ||
| @@ -236,15 +275,17 @@ void CheckForShutdown(int n); | |||
| 236 | // The message start string is designed to be unlikely to occur in normal data. | 275 | // The message start string is designed to be unlikely to occur in normal data. |
| 237 | // The characters are rarely used upper ascii, not valid as UTF-8, and produce | 276 | // The characters are rarely used upper ascii, not valid as UTF-8, and produce |
| 238 | // a large 4-byte int at any alignment. | 277 | // a large 4-byte int at any alignment. |
| 239 | // Magic bytes unique to the Bitflash network (0xbf = "BF"). Second byte bumped | 278 | // Magic bytes unique to the selected Bitflash network. Mainnet uses 0xbf = |
| 240 | // to 0x20 for the 2026 stable relaunch so the old test chain can't interfere. | 279 | // "BF"; testnet swaps the whole sequence so a test node cannot handshake with |
| 241 | static const char pchMessageStart[4] = { 0xbf, 0x20, 0x5c, 0xfd }; | 280 | // mainnet before consensus-level testnet activation exists. |
| 281 | extern char pchMessageStart[4]; | ||
| 242 | 282 | ||
| 243 | class CMessageHeader | 283 | class CMessageHeader |
| 244 | { | 284 | { |
| 245 | public: | 285 | public: |
| 246 | enum { COMMAND_SIZE=12 }; | 286 | enum { COMMAND_SIZE=12 }; |
| 247 | char pchMessageStart[sizeof(::pchMessageStart)]; | 287 | enum { MESSAGE_START_SIZE=4 }; |
| 288 | char pchMessageStart[MESSAGE_START_SIZE]; | ||
| 248 | char pchCommand[COMMAND_SIZE]; | 289 | char pchCommand[COMMAND_SIZE]; |
| 249 | unsigned int nMessageSize; | 290 | unsigned int nMessageSize; |
| 250 | 291 | ||
| @@ -335,7 +376,7 @@ public: | |||
| 335 | nServices = 0; | 376 | nServices = 0; |
| 336 | memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); | 377 | memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); |
| 337 | ip = 0; | 378 | ip = 0; |
| 338 | port = DEFAULT_PORT; | 379 | port = GetDefaultPort(); |
| 339 | nTime = GetAdjustedTime(); | 380 | nTime = GetAdjustedTime(); |
| 340 | nLastFailed = 0; | 381 | nLastFailed = 0; |
| 341 | } | 382 | } |
| @@ -365,7 +406,7 @@ public: | |||
| 365 | nServices = nServicesIn; | 406 | nServices = nServicesIn; |
| 366 | memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); | 407 | memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); |
| 367 | ip = 0; | 408 | ip = 0; |
| 368 | port = DEFAULT_PORT; | 409 | port = GetDefaultPort(); |
| 369 | nTime = GetAdjustedTime(); | 410 | nTime = GetAdjustedTime(); |
| 370 | nLastFailed = 0; | 411 | nLastFailed = 0; |
| 371 | 412 | ||
| @@ -656,9 +697,6 @@ public: | |||
| 656 | int64 nLastSend; | 697 | int64 nLastSend; |
| 657 | int64 nLastRecv; | 698 | int64 nLastRecv; |
| 658 | int64 nLastSendEmpty; | 699 | int64 nLastSendEmpty; |
| 659 | int64 nIncompleteMessageStart; | ||
| 660 | unsigned int nIncompleteMessageSize; | ||
| 661 | string strIncompleteMessageCommand; | ||
| 662 | string strBtfAddr; | 700 | string strBtfAddr; |
| 663 | string strBtfMeeting; | 701 | string strBtfMeeting; |
| 664 | 702 | ||
| @@ -699,11 +737,13 @@ public: | |||
| 699 | nLastSend = 0; | 737 | nLastSend = 0; |
| 700 | nLastRecv = 0; | 738 | nLastRecv = 0; |
| 701 | nLastSendEmpty = GetTime(); | 739 | nLastSendEmpty = GetTime(); |
| 702 | nIncompleteMessageStart = 0; | ||
| 703 | nIncompleteMessageSize = 0; | ||
| 704 | strIncompleteMessageCommand.clear(); | ||
| 705 | strBtfAddr.clear(); | 740 | strBtfAddr.clear(); |
| 706 | strBtfMeeting.clear(); | 741 | strBtfMeeting.clear(); |
| 742 | // Not waiting on anything yet. Left indeterminate, the first partial | ||
| 743 | // message this peer sends is measured against whatever was in this | ||
| 744 | // memory, and ProcessMessages drops it as unreadable on first contact. | ||
| 745 | nMsgWaitSince = 0; | ||
| 746 | nMsgWaitSize = 0; | ||
| 707 | nStartingHeight = -1; | 747 | nStartingHeight = -1; |
| 708 | 748 | ||
| 709 | // Push a version message | 749 | // Push a version message |
| @@ -798,13 +838,51 @@ public: | |||
| 798 | static int64 nLastTime; | 838 | static int64 nLastTime; |
| 799 | nLastTime = nNow = max(nNow, ++nLastTime); | 839 | nLastTime = nNow = max(nNow, ++nLastTime); |
| 800 | 840 | ||
| 801 | // Each retry is 2 minutes after the last | 841 | // Each retry is 2 minutes after the last -- and because nRequestTime |
| 802 | nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow); | 842 | // is shared across peers, the same spacing is what strings requests |
| 843 | // for one inv across its announcers. For transactions that is pacing; | ||
| 844 | // for a new block it was the stall of issue #33: nine peers announce | ||
| 845 | // the block, the first one asked does not serve it, and the ninth | ||
| 846 | // candidate is not even asked until sixteen minutes in, with the pool | ||
| 847 | // mining on the stale tip the whole time. | ||
| 848 | // | ||
| 849 | // Blocks retry on the fetch timescale, but only while we are at the | ||
| 850 | // tip. That is where the stall costs something -- the pool keeps | ||
| 851 | // handing out jobs against a dead tip -- and it is also where the | ||
| 852 | // spacing is nearly free: one block is in flight, and its body has | ||
| 853 | // almost always arrived before the second announcer's turn comes | ||
| 854 | // round, so AlreadyHave drops the duplicate before a getdata is sent. | ||
| 855 | // | ||
| 856 | // While catching up neither half holds. A peer working through a | ||
| 857 | // 500-deep queue can be minutes away from block N without anything | ||
| 858 | // being wrong, so at 15s the second announcer is asked at +15s, the | ||
| 859 | // third at +30s, and the bulk download arrives once per announcer -- | ||
| 860 | // up to eight times over. Nothing caps that: the eight-entry cap is on | ||
| 861 | // mapBlockFetch, which is a different mechanism from this spacing. | ||
| 862 | // Two minutes is the right number there, and it is what this line did | ||
| 863 | // before. Failover at the tip does not depend on this being 15s in any | ||
| 864 | // case: mapBlockFetch re-issues a stalled getdata to the next peer on | ||
| 865 | // its own timer, which is what actually fixes #33. | ||
| 866 | bool fFast = (inv.type == MSG_BLOCK && IsBlockFetchNearTip()); | ||
| 867 | int64 nRetryUsecs = (fFast ? BLOCK_FETCH_RETRY_SECS : 2 * 60) * 1000000LL; | ||
| 868 | nRequestTime = max(nRequestTime + nRetryUsecs, nNow); | ||
| 803 | mapAskFor.insert(make_pair(nRequestTime, inv)); | 869 | mapAskFor.insert(make_pair(nRequestTime, inv)); |
| 804 | } | 870 | } |
| 805 | 871 | ||
| 806 | 872 | ||
| 807 | 873 | ||
| 874 | // "sending: tx (N bytes)" alone was ~71% of a 13-hour production | ||
| 875 | // debug.log (issue #35), so tx sends are demoted to the /debugrelay-gated | ||
| 876 | // "relay" category; every other command's send trace stays on "net". | ||
| 877 | // The line is emitted in pieces across BeginMessage/EndMessage/ | ||
| 878 | // AbortMessage, so all three must agree on the category or orphaned | ||
| 879 | // "(N bytes)" fragments would leak into a plain -debug log. | ||
| 880 | // Valid only mid-message (nPushPos != -1). | ||
| 881 | const char* SendLogCategory() const | ||
| 882 | { | ||
| 883 | return strcmp(GetMessageCommand(), "tx") == 0 ? "relay" : "net"; | ||
| 884 | } | ||
| 885 | |||
| 808 | void BeginMessage(const char* pszCommand) | 886 | void BeginMessage(const char* pszCommand) |
| 809 | { | 887 | { |
| 810 | EnterCriticalSection(&cs_vSend); | 888 | EnterCriticalSection(&cs_vSend); |
| @@ -812,17 +890,19 @@ public: | |||
| 812 | AbortMessage(); | 890 | AbortMessage(); |
| 813 | nPushPos = vSend.size(); | 891 | nPushPos = vSend.size(); |
| 814 | vSend << CMessageHeader(pszCommand, 0); | 892 | vSend << CMessageHeader(pszCommand, 0); |
| 815 | if (LogAcceptsCategory("net")) printf("sending: %-12s ", pszCommand); | 893 | if (LogAcceptsCategory(SendLogCategory())) printf("sending: %-12s ", pszCommand); |
| 816 | } | 894 | } |
| 817 | 895 | ||
| 818 | void AbortMessage() | 896 | void AbortMessage() |
| 819 | { | 897 | { |
| 820 | if (nPushPos == -1) | 898 | if (nPushPos == -1) |
| 821 | return; | 899 | return; |
| 900 | // Capture before nPushPos is cleared; GetMessageCommand() needs it. | ||
| 901 | const char* pszCategory = SendLogCategory(); | ||
| 822 | vSend.resize(nPushPos); | 902 | vSend.resize(nPushPos); |
| 823 | nPushPos = -1; | 903 | nPushPos = -1; |
| 824 | LeaveCriticalSection(&cs_vSend); | 904 | LeaveCriticalSection(&cs_vSend); |
| 825 | if (LogAcceptsCategory("net")) printf("(aborted)\n"); | 905 | if (LogAcceptsCategory(pszCategory)) printf("(aborted)\n"); |
| 826 | } | 906 | } |
| 827 | 907 | ||
| 828 | void EndMessage() | 908 | void EndMessage() |
| @@ -830,7 +910,11 @@ public: | |||
| 830 | extern int nDropMessagesTest; | 910 | extern int nDropMessagesTest; |
| 831 | if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) | 911 | if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) |
| 832 | { | 912 | { |
| 833 | if (LogAcceptsCategory("net")) printf("dropmessages DROPPING SEND MESSAGE\n"); | 913 | // Same category as the "sending: " this line interrupts, so a tx |
| 914 | // does not announce its own drop under "net" having been gated | ||
| 915 | // off under "relay". nPushPos can be -1 here, and then | ||
| 916 | // GetMessageCommand() returns "" and this is "net" as before. | ||
| 917 | if (LogAcceptsCategory(SendLogCategory())) printf("dropmessages DROPPING SEND MESSAGE\n"); | ||
| 834 | AbortMessage(); | 918 | AbortMessage(); |
| 835 | return; | 919 | return; |
| 836 | } | 920 | } |
| @@ -842,10 +926,10 @@ public: | |||
| 842 | unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); | 926 | unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); |
| 843 | memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); | 927 | memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); |
| 844 | 928 | ||
| 845 | if (LogAcceptsCategory("net")) printf("(%d bytes) ", nSize); | 929 | if (LogAcceptsCategory(SendLogCategory())) printf("(%d bytes) ", nSize); |
| 846 | //for (int i = nPushPos+sizeof(CMessageHeader); i < min(vSend.size(), nPushPos+sizeof(CMessageHeader)+20U); i++) | 930 | //for (int i = nPushPos+sizeof(CMessageHeader); i < min(vSend.size(), nPushPos+sizeof(CMessageHeader)+20U); i++) |
| 847 | // printf("%02x ", vSend[i] & 0xff); | 931 | // printf("%02x ", vSend[i] & 0xff); |
| 848 | if (LogAcceptsCategory("net")) printf("\n"); | 932 | if (LogAcceptsCategory(SendLogCategory())) printf("\n"); |
| 849 | 933 | ||
| 850 | nPushPos = -1; | 934 | nPushPos = -1; |
| 851 | LeaveCriticalSection(&cs_vSend); | 935 | LeaveCriticalSection(&cs_vSend); |