Skip to content

Conversation

@aakoshh
Copy link
Contributor

@aakoshh aakoshh commented Nov 26, 2020

The PR implements what geth does to limit the entries in the K-table from the same subnet, which is a variation of Countermeasure 2 from the eclipse attack paper. In particular, by default it will not add a peer to the k-table if doing so would violate the limits. The default limits are that there cannot be more than 2 peers from the same subnet in any k-bucket, or more than 10 across all buckets, where the subnet is defined as the fist 24 bits of the IP address. All these values are configurable.

Note that the nodes and ENR records are still saved by the service, the only difference is that these values will not be inserted into the k-table, which should prevent an attacker from filling up the k-table with nodes running on the same machine, or the same subnet, thus hijacking all FindNode requests, making our node unable to discover honest peers. Because of this, Mantis should also have some measures to limit the number of TCP connections going to the same IP or subnet, because if it uses getNodes it will still get every discovered peer.

// Find any Peer records that correspond to this ID.
val peers =
nodeMap.get(peerId).map(node => Peer(node.id, toAddress(node.address))).toSeq ++
lastPongTimestampMap.keys.filter(_.id == peerId).toSeq ++
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems wasteful that we are itereating lastPongTimestampMap and bondingResultsMap maps two times here when finding all records of peer, and later when fitering this peer out. From what i known this collections can be fairly large, maybe we could do it in one pass ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I can change that. But this method won't be actually called, I just kept it for backwards compatibility with KRouter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

val blc = bucketLevelCounts |+| Map(idx -> Map(ip -> 1))

val overTheLimit =
limits.prefixLength > 0 && (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we could add some comments about each case or export this to separate funcion with some docs as this logic is little dense ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, split it out into several methods.

case counts if counts(ip) <= 0 => counts - ip
case counts => counts
}
val blc = bucketLevelCounts |+| Map(idx -> Map(ip -> -1)) match {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we could add some comments about each case or export this to separate funcion with some docs as this logic is little dense ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, split it out into several methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants