User:Gmaxwell/inbound connection management

From Bitcoin Wiki
Revision as of 21:28, 6 May 2014 by Gmaxwell (talk | contribs) (Created page with "When a new non-banned connection comes in and your node finds itself full, it needs to find a peer to eject. Currently we eject the new peer. This has some good properties, i...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

When a new non-banned connection comes in and your node finds itself full, it needs to find a peer to eject.

Currently we eject the new peer. This has some good properties, in particular, an attacker can't partition an already working node just by filling his slots. It also creates relatively little distortion on the topology of the network, (not zero: peers with more reliable tcp connections are better connected).

There are downsides, it lets an attacker block all future connections pretty easily. Most of the slots can end up filled by reliable but useless peers, etc.

We can do better: It's not necessary to use a single strategy to pick all our peers, by using different strategies for subsets of peers we can get the good connectivity properties of all of them.

In general, we want to preserve some connections for peers which have properties which are hard for attackers to have. (Either because they're expensive to have in bulk, or because they're incompatible with 'attacking').


Take the list of all inbound connections,

Exclude all trusted port peers. (this is assuming we setup a second p2p port

that is localhost bound by default that is only for trusted peers).

Remove from consideration the 10 most recent peers that gave you blocks you

accepted that extended your tip. The rationale here is that you want to
keep peers that are giving you blocks since they're provably working, but
giving you a single block shouldn't let a peer squat on a connection
forever.

Remove from consideration up to 10 peers that are from (what you believe to

be) your own local netgroup sorted by longest_mintime_between_reconnects.
The rationale here is that membership in your own specific netgroup
is hard for many attackers, even if they can get many networks on the internet.
Sorting by longest_mintime_between_reconnects reduces punishes agressive
reconnecters (e.g. spying nodes and connection fillers).

(It may be useful to separately ban agressive reconnecters, but any such

banning would have to be very conservative, so a priority here still helps)

Sort the list by good_peer_flag,HMAC(netgroup,key),longest_mintime_between_reconnects

and select 10 peers to remove from consideration.
Only remote one per netgroup in this step. 
Having a netgroup that ranks highly according to your secret preference
is costly for an attacker to achieve.

Sort the list by HMAC(addr,key),longest_conntime and select 10 peers to

remove from consideration. This helps preserve the random wiring of the
network. Only take a single connection per address in this step.
Having an address that ranks highly according to your secret preference is
costly for an attacker to achieve.

Sort by good_peer, min(observed_ping_rtt), longest_uptime, and select 10 to remove

from consideration, skipping any repeated network groups and your own netgroup.
Low rtt latency cannot be forged, making this another attacker scarce
resource... though one that results in a bad nework topology.

Remove from consideration 10 of the remaining peers with the highest

cumulative (e.g. across restarts) time connected.

Remove from consideration 10 of the remaining peers with the longest connections

this session.

Of the remaining peers, randomly select a peer to kick with a strong bias

towards the shortest connection duration.