-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ETCM-178] Disallow repeated connections and connections to self
- Loading branch information
Nicolas Tallar
committed
Oct 29, 2020
1 parent
663f0b8
commit ef84bec
Showing
10 changed files
with
282 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
72 changes: 72 additions & 0 deletions
72
src/main/scala/io/iohk/ethereum/network/ConnectedPeers.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package io.iohk.ethereum.network | ||
|
||
import java.net.InetSocketAddress | ||
|
||
import akka.actor.ActorRef | ||
import akka.util.ByteString | ||
|
||
case class ConnectedPeers( | ||
private val incomingPendingPeers: Map[PeerId, Peer], | ||
private val outgoingPendingPeers: Map[PeerId, Peer], | ||
private val handshakedPeers: Map[PeerId, Peer] | ||
) { | ||
|
||
// FIXME: Kept only for compatibility purposes, should eventually be removed | ||
lazy val peers: Map[PeerId, Peer] = outgoingPendingPeers ++ handshakedPeers | ||
|
||
private lazy val allPeers: Map[PeerId, Peer] = outgoingPendingPeers ++ handshakedPeers ++ incomingPendingPeers | ||
|
||
def isConnectionHandled(remoteAddress: InetSocketAddress): Boolean = | ||
allPeers.values.map(_.remoteAddress).toSet.contains(remoteAddress) | ||
|
||
/* | ||
We have the node id of our outgoing pending peers so we could use that in our checks, by rejecting a peer that | ||
handshaked to us with the same node id. | ||
However, with checking the node id of only handshaked peers we prioritize handshaked peers over pending ones, | ||
in the above mentioned case the repeated pending peer connection will eventually die out | ||
*/ | ||
def hasHandshakedWith(nodeId: ByteString): Boolean = | ||
handshakedPeers.values.flatMap(_.nodeId).toSet.contains(nodeId) | ||
|
||
lazy val incomingPendingPeersCount: Int = incomingPendingPeers.size | ||
lazy val incomingHandshakedPeersCount: Int = handshakedPeers.count { case (_, p) => p.incomingConnection } | ||
lazy val outgoingPeersCount: Int = peers.count { case (_, p) => !p.incomingConnection } | ||
|
||
lazy val handshakedPeersCount: Int = handshakedPeers.size | ||
lazy val pendingPeersCount: Int = incomingPendingPeersCount + outgoingPendingPeers.size | ||
|
||
def getPeer(peerId: PeerId): Option[Peer] = peers.get(peerId) | ||
|
||
def addNewPendingPeer(pendingPeer: Peer): ConnectedPeers = { | ||
if (pendingPeer.incomingConnection) | ||
copy(incomingPendingPeers = incomingPendingPeers + (pendingPeer.id -> pendingPeer)) | ||
else | ||
copy(outgoingPendingPeers = outgoingPendingPeers + (pendingPeer.id -> pendingPeer)) | ||
} | ||
|
||
def promotePeerToHandshaked(peerAfterHandshake: Peer): ConnectedPeers = { | ||
if (peerAfterHandshake.incomingConnection) | ||
copy( | ||
incomingPendingPeers = incomingPendingPeers - peerAfterHandshake.id, | ||
handshakedPeers = handshakedPeers + (peerAfterHandshake.id -> peerAfterHandshake) | ||
) | ||
else | ||
copy( | ||
outgoingPendingPeers = outgoingPendingPeers - peerAfterHandshake.id, | ||
handshakedPeers = handshakedPeers + (peerAfterHandshake.id -> peerAfterHandshake) | ||
) | ||
} | ||
|
||
def removeTerminatedPeer(peerRef: ActorRef): (Iterable[PeerId], ConnectedPeers) = { | ||
val peersId = allPeers.collect { case (id, peer) if peer.ref == peerRef => id } | ||
|
||
( | ||
peersId, | ||
ConnectedPeers(incomingPendingPeers -- peersId, outgoingPendingPeers -- peersId, handshakedPeers -- peersId) | ||
) | ||
} | ||
} | ||
|
||
object ConnectedPeers { | ||
def empty: ConnectedPeers = ConnectedPeers(Map.empty, Map.empty, Map.empty) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.