Skip to content
This repository has been archived by the owner on Aug 19, 2022. It is now read-only.

Commit

Permalink
Add allowlist limit config option
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcoPolo authored and marten-seemann committed Jul 2, 2022
1 parent d0a1694 commit eb72b52
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 44 deletions.
10 changes: 10 additions & 0 deletions limit.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type Limit interface {
type Limiter interface {
GetSystemLimits() Limit
GetTransientLimits() Limit
GetAllowlistedSystemLimits() Limit
GetAllowlistedTransientLimits() Limit
GetServiceLimits(svc string) Limit
GetServicePeerLimits(svc string) Limit
GetProtocolLimits(proto protocol.ID) Limit
Expand Down Expand Up @@ -196,6 +198,14 @@ func (l *fixedLimiter) GetTransientLimits() Limit {
return &l.Transient
}

func (l *fixedLimiter) GetAllowlistedSystemLimits() Limit {
return &l.AllowlistedSystem
}

func (l *fixedLimiter) GetAllowlistedTransientLimits() Limit {
return &l.AllowlistedTransient
}

func (l *fixedLimiter) GetServiceLimits(svc string) Limit {
sl, ok := l.Service[svc]
if !ok {
Expand Down
103 changes: 85 additions & 18 deletions limit_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ type ScalingLimitConfig struct {
TransientBaseLimit BaseLimit
TransientLimitIncrease BaseLimitIncrease

AllowlistedSystemBaseLimit BaseLimit
AllowlistedSystemLimitIncrease BaseLimitIncrease

AllowlistedTransientBaseLimit BaseLimit
AllowlistedTransientLimitIncrease BaseLimitIncrease

ServiceBaseLimit BaseLimit
ServiceLimitIncrease BaseLimitIncrease
ServiceLimits map[string]baseLimitConfig // use AddServiceLimit to modify
Expand Down Expand Up @@ -105,6 +111,12 @@ type LimitConfig struct {
System BaseLimit `json:",omitempty"`
Transient BaseLimit `json:",omitempty"`

// Limits that are applied to resources with an allowlisted multiaddr.
// These will only be used if the normal System & Transient limits are
// reached.
AllowlistedSystem BaseLimit `json:",omitempty"`
AllowlistedTransient BaseLimit `json:",omitempty"`

ServiceDefault BaseLimit `json:",omitempty"`
Service map[string]BaseLimit `json:",omitempty"`

Expand All @@ -127,6 +139,8 @@ type LimitConfig struct {
func (cfg *LimitConfig) Apply(c LimitConfig) {
cfg.System.Apply(c.System)
cfg.Transient.Apply(c.Transient)
cfg.AllowlistedSystem.Apply(c.AllowlistedSystem)
cfg.AllowlistedTransient.Apply(c.AllowlistedTransient)
cfg.ServiceDefault.Apply(c.ServiceDefault)
cfg.ProtocolDefault.Apply(c.ProtocolDefault)
cfg.ProtocolPeerDefault.Apply(c.ProtocolPeerDefault)
Expand Down Expand Up @@ -232,15 +246,17 @@ func (cfg *ScalingLimitConfig) Scale(memory int64, numFD int) LimitConfig {
scaleFactor = int((memory - 128<<20) >> 20)
}
lc := LimitConfig{
System: scale(cfg.SystemBaseLimit, cfg.SystemLimitIncrease, scaleFactor, numFD),
Transient: scale(cfg.TransientBaseLimit, cfg.TransientLimitIncrease, scaleFactor, numFD),
ServiceDefault: scale(cfg.ServiceBaseLimit, cfg.ServiceLimitIncrease, scaleFactor, numFD),
ServicePeerDefault: scale(cfg.ServicePeerBaseLimit, cfg.ServicePeerLimitIncrease, scaleFactor, numFD),
ProtocolDefault: scale(cfg.ProtocolBaseLimit, cfg.ProtocolLimitIncrease, scaleFactor, numFD),
ProtocolPeerDefault: scale(cfg.ProtocolPeerBaseLimit, cfg.ProtocolPeerLimitIncrease, scaleFactor, numFD),
PeerDefault: scale(cfg.PeerBaseLimit, cfg.PeerLimitIncrease, scaleFactor, numFD),
Conn: scale(cfg.ConnBaseLimit, cfg.ConnLimitIncrease, scaleFactor, numFD),
Stream: scale(cfg.StreamBaseLimit, cfg.ConnLimitIncrease, scaleFactor, numFD),
System: scale(cfg.SystemBaseLimit, cfg.SystemLimitIncrease, scaleFactor, numFD),
Transient: scale(cfg.TransientBaseLimit, cfg.TransientLimitIncrease, scaleFactor, numFD),
AllowlistedSystem: scale(cfg.AllowlistedSystemBaseLimit, cfg.AllowlistedSystemLimitIncrease, scaleFactor, numFD),
AllowlistedTransient: scale(cfg.AllowlistedTransientBaseLimit, cfg.AllowlistedTransientLimitIncrease, scaleFactor, numFD),
ServiceDefault: scale(cfg.ServiceBaseLimit, cfg.ServiceLimitIncrease, scaleFactor, numFD),
ServicePeerDefault: scale(cfg.ServicePeerBaseLimit, cfg.ServicePeerLimitIncrease, scaleFactor, numFD),
ProtocolDefault: scale(cfg.ProtocolBaseLimit, cfg.ProtocolLimitIncrease, scaleFactor, numFD),
ProtocolPeerDefault: scale(cfg.ProtocolPeerBaseLimit, cfg.ProtocolPeerLimitIncrease, scaleFactor, numFD),
PeerDefault: scale(cfg.PeerBaseLimit, cfg.PeerLimitIncrease, scaleFactor, numFD),
Conn: scale(cfg.ConnBaseLimit, cfg.ConnLimitIncrease, scaleFactor, numFD),
Stream: scale(cfg.StreamBaseLimit, cfg.ConnLimitIncrease, scaleFactor, numFD),
}
if cfg.ServiceLimits != nil {
lc.Service = make(map[string]BaseLimit)
Expand Down Expand Up @@ -346,6 +362,55 @@ var DefaultLimits = ScalingLimitConfig{
FDFraction: 0.25,
},

// Setting the allowlisted limits to be the same as the normal limits. The
// allowlist only activates when you reach your normal system/transient
// limits. So it's okay if these limits err on the side of being too big,
// since most of the time you won't even use any of these. Tune these down
// if you want to manager your resources against an allowlisted endpoint.
AllowlistedSystemBaseLimit: BaseLimit{
ConnsInbound: 64,
ConnsOutbound: 128,
Conns: 128,
StreamsInbound: 64 * 16,
StreamsOutbound: 128 * 16,
Streams: 128 * 16,
Memory: 128 << 20,
FD: 256,
},

AllowlistedSystemLimitIncrease: BaseLimitIncrease{
ConnsInbound: 64,
ConnsOutbound: 128,
Conns: 128,
StreamsInbound: 64 * 16,
StreamsOutbound: 128 * 16,
Streams: 128 * 16,
Memory: 1 << 30,
FDFraction: 1,
},

AllowlistedTransientBaseLimit: BaseLimit{
ConnsInbound: 32,
ConnsOutbound: 64,
Conns: 64,
StreamsInbound: 128,
StreamsOutbound: 256,
Streams: 256,
Memory: 32 << 20,
FD: 64,
},

AllowlistedTransientLimitIncrease: BaseLimitIncrease{
ConnsInbound: 16,
ConnsOutbound: 32,
Conns: 32,
StreamsInbound: 128,
StreamsOutbound: 256,
Streams: 256,
Memory: 128 << 20,
FDFraction: 0.25,
},

ServiceBaseLimit: BaseLimit{
StreamsInbound: 1024,
StreamsOutbound: 4096,
Expand Down Expand Up @@ -451,13 +516,15 @@ var infiniteBaseLimit = BaseLimit{
// InfiniteLimits are a limiter configuration that uses infinite limits, thus effectively not limiting anything.
// Keep in mind that the operating system limits the number of file descriptors that an application can use.
var InfiniteLimits = LimitConfig{
System: infiniteBaseLimit,
Transient: infiniteBaseLimit,
ServiceDefault: infiniteBaseLimit,
ServicePeerDefault: infiniteBaseLimit,
ProtocolDefault: infiniteBaseLimit,
ProtocolPeerDefault: infiniteBaseLimit,
PeerDefault: infiniteBaseLimit,
Conn: infiniteBaseLimit,
Stream: infiniteBaseLimit,
System: infiniteBaseLimit,
Transient: infiniteBaseLimit,
AllowlistedSystem: infiniteBaseLimit,
AllowlistedTransient: infiniteBaseLimit,
ServiceDefault: infiniteBaseLimit,
ServicePeerDefault: infiniteBaseLimit,
ProtocolDefault: infiniteBaseLimit,
ProtocolPeerDefault: infiniteBaseLimit,
PeerDefault: infiniteBaseLimit,
Conn: infiniteBaseLimit,
Stream: infiniteBaseLimit,
}
4 changes: 2 additions & 2 deletions rcmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,9 @@ func NewResourceManager(limits Limiter, opts ...Option) (network.ResourceManager
r.transient = newTransientScope(limits.GetTransientLimits(), r, "transient", r.system.resourceScope)
r.transient.IncRef()

r.allowlistedSystem = newSystemScope(limits.GetSystemLimits(), r, "allowlistedSystem")
r.allowlistedSystem = newSystemScope(limits.GetAllowlistedSystemLimits(), r, "allowlistedSystem")
r.allowlistedSystem.IncRef()
r.allowlistedTransient = newTransientScope(limits.GetTransientLimits(), r, "allowlistedTransient", r.allowlistedSystem.resourceScope)
r.allowlistedTransient = newTransientScope(limits.GetAllowlistedTransientLimits(), r, "allowlistedTransient", r.allowlistedSystem.resourceScope)
r.allowlistedTransient.IncRef()

r.cancelCtx, r.cancel = context.WithCancel(context.Background())
Expand Down
42 changes: 18 additions & 24 deletions rcmgr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -977,13 +977,26 @@ func TestResourceManager(t *testing.T) {
func TestResourceManagerWithAllowlist(t *testing.T) {
peerA := test.RandPeerIDFatal(t)

limits := DefaultLimits.Scale(1<<30, 100)
limits := DefaultLimits.AutoScale()
limits.System.Conns = 0
limits.System.ConnsInbound = 0
limits.System.ConnsOutbound = 0
limits.Transient.Conns = 0
limits.Transient.ConnsInbound = 0
limits.Transient.ConnsOutbound = 0

baseLimit := BaseLimit{
Conns: 2,
ConnsInbound: 2,
ConnsOutbound: 1,
}
baseLimit.Apply(limits.AllowlistedSystem)
limits.AllowlistedSystem = baseLimit

baseLimit = BaseLimit{
Conns: 1,
ConnsInbound: 1,
ConnsOutbound: 1,
}
baseLimit.Apply(limits.AllowlistedTransient)
limits.AllowlistedTransient = baseLimit

rcmgr, err := NewResourceManager(NewFixedLimiter(limits), WithAllowlistedMultiaddrs([]multiaddr.Multiaddr{
multiaddr.StringCast("/ip4/1.2.3.4"),
multiaddr.StringCast("/ip4/4.3.2.1/p2p/" + peerA.String()),
Expand All @@ -992,25 +1005,6 @@ func TestResourceManagerWithAllowlist(t *testing.T) {
t.Fatal(err)
}

{
// Setup allowlist. TODO, replace this with a config once config changes are in
r := rcmgr.(*resourceManager)

sysLimit := limits.System
sysLimit.Conns = 2
sysLimit.ConnsInbound = 2
sysLimit.ConnsOutbound = 1
r.allowlistedSystem = newSystemScope(&sysLimit, r, "allowlistedSystem")
r.allowlistedSystem.IncRef()

transLimit := limits.Transient
transLimit.Conns = 1
transLimit.ConnsInbound = 1
transLimit.ConnsOutbound = 1
r.allowlistedTransient = newTransientScope(&transLimit, r, "allowlistedTransient", r.allowlistedSystem.resourceScope)
r.allowlistedTransient.IncRef()
}

// A connection comes in from a non-allowlisted ip address
_, err = rcmgr.OpenConnection(network.DirInbound, true, multiaddr.StringCast("/ip4/1.2.3.5"))
if err == nil {
Expand Down

0 comments on commit eb72b52

Please sign in to comment.