diff options
Diffstat (limited to 'src/net.h')
| -rw-r--r-- | src/net.h | 90 |
1 files changed, 83 insertions, 7 deletions
| @@ -23,6 +23,12 @@ enum | |||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | // Defined in main.cpp. True while this node is tracking the tip rather than | ||
| 27 | // still catching up, measured off the age of our own best block -- see there | ||
| 28 | // for why that and not a peer-reported height. Declared here because net.h is | ||
| 29 | // parsed before main.h and CNode::AskFor needs it. | ||
| 30 | bool IsBlockFetchNearTip(); | ||
| 31 | |||
| 26 | bool GetMyExternalIP(unsigned int& ipRet); | 32 | bool GetMyExternalIP(unsigned int& ipRet); |
| 27 | CNode* ConnectNodeBtf(const string& strBtfAddr); | 33 | CNode* ConnectNodeBtf(const string& strBtfAddr); |
| 28 | CNode* ConnectNodeBtfResolved(const string& strBtfAddr, const string& strMeeting, | 34 | CNode* ConnectNodeBtfResolved(const string& strBtfAddr, const string& strMeeting, |
| @@ -89,6 +95,15 @@ static const int BTF_RECV_TIMEOUT_SECS = 30 * 60; | |||
| 89 | static const int BTF_SEND_STALL_SECS = 10 * 60; | 95 | static const int BTF_SEND_STALL_SECS = 10 * 60; |
| 90 | static const int BTF_HANDSHAKE_GRACE_SECS = 60; | 96 | static const int BTF_HANDSHAKE_GRACE_SECS = 60; |
| 91 | 97 | ||
| 98 | // How long a requested block gets before it is asked for again, in seconds. | ||
| 99 | // Used twice: CNode::AskFor spaces the queued per-announcer block retries this | ||
| 100 | // far apart instead of the two minutes transactions get, and the failover | ||
| 101 | // sweep in main.cpp re-issues a getdata to a different peer once a sent | ||
| 102 | // request has gone unanswered this long. A block body is at most 1 MB and | ||
| 103 | // somebody demonstrably has it -- they announced it -- so on this timescale | ||
| 104 | // "not here yet" means "not coming from that peer", not "still in transit". | ||
| 105 | static const int BLOCK_FETCH_RETRY_SECS = 15; | ||
| 106 | |||
| 92 | // A serialized object cannot be larger than MAX_SIZE, so no valid network | 107 | // A serialized object cannot be larger than MAX_SIZE, so no valid network |
| 93 | // message needs the old 256 MB header allowance. Keep the wire cap aligned with | 108 | // message needs the old 256 MB header allowance. Keep the wire cap aligned with |
| 94 | // what the deserializer can accept. How long a peer may sit on a partial | 109 | // what the deserializer can accept. How long a peer may sit on a partial |
| @@ -109,6 +124,23 @@ static const unsigned int MAX_PROTOCOL_MESSAGE_SIZE = MAX_SIZE; | |||
| 109 | // 125 is Bitcoin's number and remains a conservative public-node default. | 124 | // 125 is Bitcoin's number and remains a conservative public-node default. |
| 110 | static const unsigned int MAX_CONNECTIONS = 125; | 125 | static const unsigned int MAX_CONNECTIONS = 125; |
| 111 | 126 | ||
| 127 | // Cap inbound connections from any single address. Without it one source can | ||
| 128 | // hold every slot up to MAX_CONNECTIONS -- exactly what happened to the | ||
| 129 | // rendezvous relays, where a single IP parked hundreds of connections and | ||
| 130 | // starved real peers. A legitimate peer, even a relay talking to a relay, | ||
| 131 | // needs only a handful; 32 leaves generous room while denying any one address | ||
| 132 | // more than a quarter of the table. The firewall connlimit on the relays does | ||
| 133 | // the same thing a layer lower; this makes every build carry the defense. | ||
| 134 | // | ||
| 135 | // Loopback (127.0.0.0/8) is exempt in the accept path. A managed-Tor node | ||
| 136 | // receives every inbound onion peer over its local hidden-service listener, so | ||
| 137 | // they all appear as 127.0.0.1 -- capping loopback would cap onion peers as a | ||
| 138 | // group, which is exactly wrong for a network moving toward onion-only. The | ||
| 139 | // global MAX_CONNECTIONS still bounds the total; a per-onion-identity limit, | ||
| 140 | // applied once identity is known after accept(), is the right future tool for | ||
| 141 | // onion floods. | ||
| 142 | static const unsigned int MAX_CONNECTIONS_PER_IP = 32; | ||
| 143 | |||
| 112 | // A node marked for disconnect is normally held until its buffers drain, so | 144 | // A node marked for disconnect is normally held until its buffers drain, so |
| 113 | // a last message still goes out. But vSend cannot drain through a socket | 145 | // a last message still goes out. But vSend cannot drain through a socket |
| 114 | // whose far end is gone, and that made such a node immortal: it stayed in | 146 | // whose far end is gone, and that made such a node immortal: it stayed in |
| @@ -795,13 +827,51 @@ public: | |||
| 795 | static int64 nLastTime; | 827 | static int64 nLastTime; |
| 796 | nLastTime = nNow = max(nNow, ++nLastTime); | 828 | nLastTime = nNow = max(nNow, ++nLastTime); |
| 797 | 829 | ||
| 798 | // Each retry is 2 minutes after the last | 830 | // Each retry is 2 minutes after the last -- and because nRequestTime |
| 799 | nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow); | 831 | // is shared across peers, the same spacing is what strings requests |
| 832 | // for one inv across its announcers. For transactions that is pacing; | ||
| 833 | // for a new block it was the stall of issue #33: nine peers announce | ||
| 834 | // the block, the first one asked does not serve it, and the ninth | ||
| 835 | // candidate is not even asked until sixteen minutes in, with the pool | ||
| 836 | // mining on the stale tip the whole time. | ||
| 837 | // | ||
| 838 | // Blocks retry on the fetch timescale, but only while we are at the | ||
| 839 | // tip. That is where the stall costs something -- the pool keeps | ||
| 840 | // handing out jobs against a dead tip -- and it is also where the | ||
| 841 | // spacing is nearly free: one block is in flight, and its body has | ||
| 842 | // almost always arrived before the second announcer's turn comes | ||
| 843 | // round, so AlreadyHave drops the duplicate before a getdata is sent. | ||
| 844 | // | ||
| 845 | // While catching up neither half holds. A peer working through a | ||
| 846 | // 500-deep queue can be minutes away from block N without anything | ||
| 847 | // being wrong, so at 15s the second announcer is asked at +15s, the | ||
| 848 | // third at +30s, and the bulk download arrives once per announcer -- | ||
| 849 | // up to eight times over. Nothing caps that: the eight-entry cap is on | ||
| 850 | // mapBlockFetch, which is a different mechanism from this spacing. | ||
| 851 | // Two minutes is the right number there, and it is what this line did | ||
| 852 | // before. Failover at the tip does not depend on this being 15s in any | ||
| 853 | // case: mapBlockFetch re-issues a stalled getdata to the next peer on | ||
| 854 | // its own timer, which is what actually fixes #33. | ||
| 855 | bool fFast = (inv.type == MSG_BLOCK && IsBlockFetchNearTip()); | ||
| 856 | int64 nRetryUsecs = (fFast ? BLOCK_FETCH_RETRY_SECS : 2 * 60) * 1000000LL; | ||
| 857 | nRequestTime = max(nRequestTime + nRetryUsecs, nNow); | ||
| 800 | mapAskFor.insert(make_pair(nRequestTime, inv)); | 858 | mapAskFor.insert(make_pair(nRequestTime, inv)); |
| 801 | } | 859 | } |
| 802 | 860 | ||
| 803 | 861 | ||
| 804 | 862 | ||
| 863 | // "sending: tx (N bytes)" alone was ~71% of a 13-hour production | ||
| 864 | // debug.log (issue #35), so tx sends are demoted to the /debugrelay-gated | ||
| 865 | // "relay" category; every other command's send trace stays on "net". | ||
| 866 | // The line is emitted in pieces across BeginMessage/EndMessage/ | ||
| 867 | // AbortMessage, so all three must agree on the category or orphaned | ||
| 868 | // "(N bytes)" fragments would leak into a plain -debug log. | ||
| 869 | // Valid only mid-message (nPushPos != -1). | ||
| 870 | const char* SendLogCategory() const | ||
| 871 | { | ||
| 872 | return strcmp(GetMessageCommand(), "tx") == 0 ? "relay" : "net"; | ||
| 873 | } | ||
| 874 | |||
| 805 | void BeginMessage(const char* pszCommand) | 875 | void BeginMessage(const char* pszCommand) |
| 806 | { | 876 | { |
| 807 | EnterCriticalSection(&cs_vSend); | 877 | EnterCriticalSection(&cs_vSend); |
| @@ -809,17 +879,19 @@ public: | |||
| 809 | AbortMessage(); | 879 | AbortMessage(); |
| 810 | nPushPos = vSend.size(); | 880 | nPushPos = vSend.size(); |
| 811 | vSend << CMessageHeader(pszCommand, 0); | 881 | vSend << CMessageHeader(pszCommand, 0); |
| 812 | if (LogAcceptsCategory("net")) printf("sending: %-12s ", pszCommand); | 882 | if (LogAcceptsCategory(SendLogCategory())) printf("sending: %-12s ", pszCommand); |
| 813 | } | 883 | } |
| 814 | 884 | ||
| 815 | void AbortMessage() | 885 | void AbortMessage() |
| 816 | { | 886 | { |
| 817 | if (nPushPos == -1) | 887 | if (nPushPos == -1) |
| 818 | return; | 888 | return; |
| 889 | // Capture before nPushPos is cleared; GetMessageCommand() needs it. | ||
| 890 | const char* pszCategory = SendLogCategory(); | ||
| 819 | vSend.resize(nPushPos); | 891 | vSend.resize(nPushPos); |
| 820 | nPushPos = -1; | 892 | nPushPos = -1; |
| 821 | LeaveCriticalSection(&cs_vSend); | 893 | LeaveCriticalSection(&cs_vSend); |
| 822 | if (LogAcceptsCategory("net")) printf("(aborted)\n"); | 894 | if (LogAcceptsCategory(pszCategory)) printf("(aborted)\n"); |
| 823 | } | 895 | } |
| 824 | 896 | ||
| 825 | void EndMessage() | 897 | void EndMessage() |
| @@ -827,7 +899,11 @@ public: | |||
| 827 | extern int nDropMessagesTest; | 899 | extern int nDropMessagesTest; |
| 828 | if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) | 900 | if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) |
| 829 | { | 901 | { |
| 830 | if (LogAcceptsCategory("net")) printf("dropmessages DROPPING SEND MESSAGE\n"); | 902 | // Same category as the "sending: " this line interrupts, so a tx |
| 903 | // does not announce its own drop under "net" having been gated | ||
| 904 | // off under "relay". nPushPos can be -1 here, and then | ||
| 905 | // GetMessageCommand() returns "" and this is "net" as before. | ||
| 906 | if (LogAcceptsCategory(SendLogCategory())) printf("dropmessages DROPPING SEND MESSAGE\n"); | ||
| 831 | AbortMessage(); | 907 | AbortMessage(); |
| 832 | return; | 908 | return; |
| 833 | } | 909 | } |
| @@ -839,10 +915,10 @@ public: | |||
| 839 | unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); | 915 | unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); |
| 840 | memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); | 916 | memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); |
| 841 | 917 | ||
| 842 | if (LogAcceptsCategory("net")) printf("(%d bytes) ", nSize); | 918 | if (LogAcceptsCategory(SendLogCategory())) printf("(%d bytes) ", nSize); |
| 843 | //for (int i = nPushPos+sizeof(CMessageHeader); i < min(vSend.size(), nPushPos+sizeof(CMessageHeader)+20U); i++) | 919 | //for (int i = nPushPos+sizeof(CMessageHeader); i < min(vSend.size(), nPushPos+sizeof(CMessageHeader)+20U); i++) |
| 844 | // printf("%02x ", vSend[i] & 0xff); | 920 | // printf("%02x ", vSend[i] & 0xff); |
| 845 | if (LogAcceptsCategory("net")) printf("\n"); | 921 | if (LogAcceptsCategory(SendLogCategory())) printf("\n"); |
| 846 | 922 | ||
| 847 | nPushPos = -1; | 923 | nPushPos = -1; |
| 848 | LeaveCriticalSection(&cs_vSend); | 924 | LeaveCriticalSection(&cs_vSend); |