backport from https://github.com/decred/dcrd/pull/2253
When a peer sends a notfound message, remove the hash from requested
map. Also increase notfound ban score and return early if it
disconnects the peer.
This addresses an issue where the server ends up tracking a peer that
has been disconnected due to it processing a peer's `done` message
before its `add` message.
This was previously done within the OnVersion listener, which should not
be a blocking operation. It turns out that requesting these messages
there can lead to blocking due to peers not being able to process
messages since their message queues have yet to start. Therefore, we'll
now request within handleAddPeerMsg, which should allow it to go
through.
This change is needed as part of requiring peers to also send a verack
message following their version message during protocol negotiation.
Peers were previously added to the SyncManager before their message
queues were started, causing the server to stall if a peer didn't
provide a timely verack response following their version. We now do this
within OnVerAck, which happens shortly before peer message queues are
started.
This makes the logic a bit more unified as previously it was possible we
for us to report the new peer to the SyncManager, but for whatever
reason failed to track the peer in the server internally within AddPeer.
This change ensures this can no longer happen.
Doing so ensures we reach our target number of outbound peers as soon as
possible. This is only necessary after calls to connmgr.Remove, as these
won't request a new peer connection.
The Disconnect method would still attempt to reconnect to the same
peer, which could cause us to reconnect to bad/unstable peers if we came
across them. Instead, we'll now use Remove whenever we intend to remove
a peer that is not persistent.
We do this to ensure the address manager contains live addresses.
Previously, addresses with which we established connections with would
not be marked as connected because it would be done once we disconnect
peers. Given that we don't process all of the disconnect logic when
we're shutting down, addresses of stable and good peers would never be
marked as connected unless the connection was lost during operation.
This modifies the OnVersion handler for server peers to use a local
variable for the remote address of the peer in order to avoid grabbing
the mutex multiple times.
There are no functional changes.
Backported from Decred.
This changes the server peers OnVersion handler to only advertise the
server as a viable target for inbound connections when the server
believes it is close the best known tip.
Backported from Decred.
This modifies the OnVersion handler for server peers to use a local
variable for the inbound status of the peer in order to avoid grabbing
the mutex multiple times.
While here, it also does some light cleanup. There are no functional
changes.
Backported from Decred.
This adds code to update the address manager services for a known
address to the services advertised by peers when they are connected to
via an outbound connection. It is only done for outbound connections to
help prevent malicious behavior from inbound connections.
Backported from Decred.
This modifies the OnVersion callback to allow a reject message to be
returned in which case the message will be sent to the peer and the peer
will be disconnected.
Backported from Decred.
This modifies the negotiation logic to ensure the callback has the
opportunity to see the message before the peer is disconnected and
improves the error handling when reading the remote version message.
It also has the side effect of ensuring the protocol version is
negotiated before sending reject messages with the exception of the
first message not being a version message since negotiation is not
possible in that case.
This is being changed because it is useful for the server to see the
message regardless in order to have the opportunity to things such as
update the address manager and reject peers that don't have desired
services.
Backported from Decred.
In this commit, we fix a panic bug that can arise when we attempt to
process a cf checkpoint message from a remote peer. Before this commit,
if the size of the checkpoint cache was large than the number of
checkpoints requested by the peer, we would panic with an out of bounds
error. In order to prevent, this we'll now use the size of the requested
set of hashes as our bound to ensure that we don't panic.
In this commit, we modify the locking scheme when serving cf checkpoints
for peers to allow the server to serve multiple peers at the same time.
Before this commit, we would first grab the write lock, check to see for
expansion, then release the read lock. In this commit we reverse this
and instead will grab the read lock, and upgrade to the write lock if we
need to actually expand the size of the cache.
In this commit, we fix a bug in the way that we previously attempted to
server cfcheckpoints. In the prior version we would never actually
fetch the current length of the cache. As a result, after the first time
the checkpoints were fetched, we would always continually grow the
cache rather than using what's there if sufficient.
In this commit, we fix this behavior by always checking the length, then
either keeping the rite lock, or downgrading to a read lock if the size
was sufficient.