ip colocation is parameterizable. If set to 0, it is disabled (#2323)

The "ip colocation" concept refers to the maximum allowed peers
from the same IP address. For example, we allow disabling this limit when the
node works behind a reverse proxy.
This commit is contained in:
Ivan FB 2024-01-02 14:01:18 +01:00 committed by GitHub
parent 07beea0209
commit ebad0385ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 5 deletions

View File

@ -303,6 +303,7 @@ proc initNode(conf: WakuNodeConf,
sendSignedPeerRecord = conf.relayPeerExchange, # We send our own signed peer record when peer exchange enabled
agentString = some(conf.agentString)
)
builder.withColocationLimit(conf.colocationLimit)
builder.withPeerManagerConfig(maxRelayPeers = conf.maxRelayPeers)
node = ? builder.build().mapErr(proc (err: string): string = "failed to create waku node instance: " & err)

View File

@ -17,7 +17,8 @@ import
../../waku/common/confutils/envvar/defs as confEnvvarDefs,
../../waku/common/confutils/envvar/std/net as confEnvvarNet,
../../waku/common/logging,
../../waku/waku_enr
../../waku/waku_enr,
../../waku/node/peer_manager
export
confTomlDefs,
@ -143,6 +144,11 @@ type
defaultValue: 50
name: "max-connections" }: uint16
colocationLimit* {.
desc: "Max num allowed peers from the same IP. Set it to 0 to remove the limitation."
defaultValue: defaultColocationLimit()
name: "ip-colocation-limit" }: int
maxRelayPeers* {.
desc: "Maximum allowed number of relay peers."
name: "max-relay-peers" }: Option[int]
@ -524,6 +530,9 @@ proc defaultListenAddress*(): IpAddress =
# Maybe there should be a config option for this.
(static parseIpAddress("0.0.0.0"))
proc defaultColocationLimit*(): int =
return DefaultColocationLimit
proc parseCmdArg*(T: type Port, p: string): T =
try:
Port(parseInt(p))

View File

@ -35,6 +35,7 @@ type
# Peer manager config
maxRelayPeers: Option[int]
colocationLimit: int
# Libp2p switch
switchMaxConnections: Option[int]
@ -107,7 +108,9 @@ proc withPeerManagerConfig*(builder: var WakuNodeBuilder,
maxRelayPeers = none(int)) =
builder.maxRelayPeers = maxRelayPeers
proc withColocationLimit*(builder: var WakuNodeBuilder,
colocationLimit: int) =
builder.colocationLimit = colocationLimit
## Waku switch
@ -170,6 +173,7 @@ proc build*(builder: WakuNodeBuilder): Result[WakuNode, string] =
switch = switch,
storage = builder.peerStorage.get(nil),
maxRelayPeers = builder.maxRelayPeers,
colocationLimit = builder.colocationLimit,
)
var node: WakuNode

View File

@ -62,7 +62,7 @@ const
LogAndMetricsInterval = chronos.minutes(3)
# Max peers that we allow from the same IP
ColocationLimit = 5
DefaultColocationLimit* = 5
type
PeerManager* = ref object of RootObj
@ -375,7 +375,9 @@ proc onPeerEvent(pm: PeerManager, peerId: PeerId, event: PeerEvent) {.async.} =
pm.ipTable.mgetOrPut(ip.get, newSeq[PeerId]()).add(peerId)
let peersBehindIp = pm.ipTable[ip.get]
if peersBehindIp.len > pm.colocationLimit:
# pm.colocationLimit == 0 disables the ip colocation limit
if pm.colocationLimit != 0 and
peersBehindIp.len > pm.colocationLimit:
# in theory this should always be one, but just in case
for peerId in peersBehindIp[0..<(peersBehindIp.len - pm.colocationLimit)]:
debug "Pruning connection due to ip colocation", peerId = peerId, ip = ip
@ -411,7 +413,7 @@ proc new*(T: type PeerManager,
initialBackoffInSec = InitialBackoffInSec,
backoffFactor = BackoffFactor,
maxFailedAttempts = MaxFailedAttempts,
colocationLimit = ColocationLimit,): PeerManager =
colocationLimit = DefaultColocationLimit,): PeerManager =
let capacity = switch.peerStore.capacity
let maxConnections = switch.connManager.inSema.size