From 89ffd1cb6782e549b2c2ba4b71aa14ebf61d775c Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 10 Nov 2022 17:17:14 +0100 Subject: [PATCH 01/16] chore: bump version to v0.17.0-rc1 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 7639d27dae8..d03126e547c 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.17.0-dev" +const CurrentVersionNumber = "0.17.0-rc1" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From e58cde1789835422a588e91a133904d0a9216f1d Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Tue, 15 Nov 2022 17:01:08 +0100 Subject: [PATCH 02/16] docs: Deprecate Reframe on docs. (#9401) --- docs/config.md | 61 +++++++++++--------------------------------------- 1 file changed, 13 insertions(+), 48 deletions(-) diff --git a/docs/config.md b/docs/config.md index af7e7c672e9..58d62a43322 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1299,8 +1299,7 @@ Contains options for content, peer, and IPNS routing mechanisms. Map of additional Routers. Allows for extending the default routing (DHT) with alternative Router -implementations, such as custom DHTs and delegated routing based -on the [reframe protocol](https://github.com/ipfs/specs/tree/main/reframe#readme). +implementations. The map key is a name of a Router, and the value is its configuration. @@ -1316,7 +1315,7 @@ It specifies the routing type that will be created. Currently supported types: -- `reframe` (delegated routing based on the [reframe protocol](https://github.com/ipfs/specs/tree/main/reframe#readme)) +- `reframe` **(DEPRECATED)** (delegated routing based on the [reframe protocol](https://github.com/ipfs/specs/tree/main/reframe#readme)) - `dht` - `parallel` and `sequential`: Helpers that can be used to run several routers sequentially or in parallel. @@ -1328,7 +1327,7 @@ Type: `string` Parameters needed to create the specified router. Supported params per router type: -Reframe: +Reframe **(DEPRECATED)**: - `Endpoint` (mandatory): URL that will be used to connect to a specified router. DHT: @@ -1351,21 +1350,6 @@ Sequential: - `IgnoreErrors:bool`: It will specify if that router should be ignored if an error occurred. - `Timeout:duration`: Global timeout. It accepts strings compatible with Go `time.ParseDuration(string)`. -**Examples:** - -To add router provided by _Store the Index_ team at [cid.contact](https://cid.contact): - -```console -$ ipfs config Routing.Routers.CidContact --json '{ - "Type": "reframe", - "Parameters": { - "Endpoint": "https://cid.contact/reframe" - } -}' -``` - -Anyone can create and run their own Reframe endpoint, and experiment with custom routing logic. See [`someguy`](https://github.com/aschmahmann/someguy) example, which proxies requests to BOTH the IPFS Public DHT AND an Indexer node. Protocol Labs provides a public instance at `https://routing.delegate.ipfs.io/reframe`. - Default: `{}` (use the safe implicit defaults) Type: `object[string->string]` @@ -1381,44 +1365,25 @@ Type: `object[string->object]` **Examples:** -To use the previously added `CidContact` reframe router on all methods: - -```console -$ ipfs config Routing.Methods --json '{ - "find-peers": { - "RouterName": "CidContact" - }, - "find-providers": { - "RouterName": "CidContact" - }, - "get-ipns": { - "RouterName": "CidContact" - }, - "provide": { - "RouterName": "CidContact" - }, - "put-ipns": { - "RouterName": "CidContact" - } - }' -``` -Complete example using 3 Routers, reframe, DHT and parallel. +Complete example using 2 Routers, DHT (LAN/WAN) and parallel. ``` $ ipfs config Routing.Type --json '"custom"' -$ ipfs config Routing.Routers.CidContact --json '{ - "Type": "reframe", +$ ipfs config Routing.Routers.WanDHT --json '{ + "Type": "dht", "Parameters": { - "Endpoint": "https://cid.contact/reframe" + "Mode": "auto", + "PublicIPNetwork": true, + "AcceleratedDHTClient": false } }' -$ ipfs config Routing.Routers.WanDHT --json '{ +$ ipfs config Routing.Routers.LanDHT --json '{ "Type": "dht", "Parameters": { "Mode": "auto", - "PublicIPNetwork": true, + "PublicIPNetwork": false, "AcceleratedDHTClient": false } }' @@ -1428,7 +1393,7 @@ $ ipfs config Routing.Routers.ParallelHelper --json '{ "Parameters": { "Routers": [ { - "RouterName" : "CidContact", + "RouterName" : "LanDHT", "IgnoreErrors" : true, "Timeout": "3s" }, @@ -1453,7 +1418,7 @@ ipfs config Routing.Methods --json '{ "RouterName": "ParallelHelper" }, "provide": { - "RouterName": "WanDHT" + "RouterName": "ParallelHelper" }, "put-ipns": { "RouterName": "ParallelHelper" From fb42b53f58e989fd2897d814cd5edfa52eddcb62 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Tue, 15 Nov 2022 10:36:22 +0100 Subject: [PATCH 03/16] Fix RM errors when acceleratedDHT is active Signed-off-by: Antonio Navarro Perez --- core/node/groups.go | 2 +- core/node/libp2p/rcmgr.go | 6 +++--- core/node/libp2p/rcmgr_defaults.go | 32 ++++++++++++++++++++++++------ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/core/node/groups.go b/core/node/groups.go index fca984650d9..6a821becab2 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -147,7 +147,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { BaseLibP2P, // Services (resource management) - fx.Provide(libp2p.ResourceManager(cfg.Swarm)), + fx.Provide(libp2p.ResourceManager(cfg.Swarm, cfg.Experimental.AcceleratedDHTClient)), fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)), fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.AppendAnnounce, cfg.Addresses.NoAnnounce)), fx.Provide(libp2p.SmuxTransport(cfg.Swarm.Transports)), diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 49c9d382399..0de4fbe6408 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -29,7 +29,7 @@ const NetLimitTraceFilename = "rcmgr.json.gz" var ErrNoResourceMgr = fmt.Errorf("missing ResourceMgr: make sure the daemon is running with Swarm.ResourceMgr.Enabled") -func ResourceManager(cfg config.SwarmConfig) interface{} { +func ResourceManager(cfg config.SwarmConfig, acceleratedDHT bool) interface{} { return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, repo repo.Repo) (network.ResourceManager, Libp2pOpts, error) { var manager network.ResourceManager var opts Libp2pOpts @@ -52,7 +52,7 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { return nil, opts, fmt.Errorf("opening IPFS_PATH: %w", err) } - limits, err := createDefaultLimitConfig(cfg) + limits, err := createDefaultLimitConfig(cfg, acceleratedDHT) if err != nil { return nil, opts, err } @@ -513,7 +513,7 @@ func NetResetLimit(mgr network.ResourceManager, repo repo.Repo, scope string) (r return result, fmt.Errorf("reading config to reset limit: %w", err) } - defaults, err := createDefaultLimitConfig(cfg.Swarm) + defaults, err := createDefaultLimitConfig(cfg.Swarm, cfg.Experimental.AcceleratedDHTClient) if err != nil { return result, fmt.Errorf("creating default limit config: %w", err) } diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index 3ff8b55dd26..2c1f3d93a8c 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -89,7 +89,7 @@ var noLimitIncrease = rcmgr.BaseLimitIncrease{ // maxMemory, maxFD, or maxConns with Swarm.HighWater.ConnMgr. // 3. Power user - They specify all the limits they want set via Swarm.ResourceMgr.Limits // and we don't do any defaults/overrides. We pass that config blindly into libp2p resource manager. -func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.LimitConfig, error) { +func createDefaultLimitConfig(cfg config.SwarmConfig, acceleratedDHT bool) (rcmgr.LimitConfig, error) { maxMemoryDefaultString := humanize.Bytes(uint64(memory.TotalMemory()) / 8) maxMemoryString := cfg.ResourceMgr.MaxMemory.WithDefault(maxMemoryDefaultString) maxMemory, err := humanize.ParseBytes(maxMemoryString) @@ -132,9 +132,29 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.LimitConfig, error) StreamsOutbound: 0, }, - // Just go with what libp2p does - TransientBaseLimit: rcmgr.DefaultLimits.TransientBaseLimit, - TransientLimitIncrease: rcmgr.DefaultLimits.TransientLimitIncrease, + TransientBaseLimit: rcmgr.BaseLimit{ + Streams: bigEnough, + StreamsInbound: rcmgr.DefaultLimits.TransientBaseLimit.StreamsInbound, + StreamsOutbound: bigEnough, + Conns: bigEnough, + ConnsInbound: rcmgr.DefaultLimits.TransientBaseLimit.ConnsInbound, + ConnsOutbound: bigEnough, + FD: rcmgr.DefaultLimits.TransientBaseLimit.FD, + Memory: rcmgr.DefaultLimits.TransientBaseLimit.Memory, + }, + + TransientLimitIncrease: rcmgr.BaseLimitIncrease{ + Memory: rcmgr.DefaultLimits.TransientLimitIncrease.Memory, + FDFraction: rcmgr.DefaultLimits.TransientLimitIncrease.FDFraction, + + Conns: 0, + ConnsInbound: rcmgr.DefaultLimits.TransientLimitIncrease.ConnsInbound, + ConnsOutbound: 0, + + Streams: 0, + StreamsInbound: rcmgr.DefaultLimits.TransientLimitIncrease.StreamsInbound, + StreamsOutbound: 0, + }, // Lets get out of the way of the allow list functionality. // If someone specified "Swarm.ResourceMgr.Allowlist" we should let it go through. @@ -197,8 +217,8 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.LimitConfig, error) defaultLimitConfig := scalingLimitConfig.Scale(int64(maxMemory), int(numFD)) - // If a high water mark is set: - if cfg.ConnMgr.Type == "basic" { + // If a high water mark is set (ignore when using accelerated DHT): + if cfg.ConnMgr.Type == "basic" && !acceleratedDHT { // set the connection limit higher than high water mark so that the ConnMgr has "space and time" to close "least useful" connections. defaultLimitConfig.System.Conns = 2 * cfg.ConnMgr.HighWater log.Info("adjusted default resource manager System.Conns limits to match ConnMgr.HighWater value of %s", cfg.ConnMgr.HighWater) From 377d4e9938eddb7c589e53c26d36b181e035cc08 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Tue, 15 Nov 2022 17:22:41 +0100 Subject: [PATCH 04/16] Remove limitation by HighWater param. Signed-off-by: Antonio Navarro Perez --- core/node/groups.go | 2 +- core/node/libp2p/rcmgr.go | 6 +++--- core/node/libp2p/rcmgr_defaults.go | 23 ++++++++++++----------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/core/node/groups.go b/core/node/groups.go index 6a821becab2..fca984650d9 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -147,7 +147,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { BaseLibP2P, // Services (resource management) - fx.Provide(libp2p.ResourceManager(cfg.Swarm, cfg.Experimental.AcceleratedDHTClient)), + fx.Provide(libp2p.ResourceManager(cfg.Swarm)), fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)), fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.AppendAnnounce, cfg.Addresses.NoAnnounce)), fx.Provide(libp2p.SmuxTransport(cfg.Swarm.Transports)), diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 0de4fbe6408..49c9d382399 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -29,7 +29,7 @@ const NetLimitTraceFilename = "rcmgr.json.gz" var ErrNoResourceMgr = fmt.Errorf("missing ResourceMgr: make sure the daemon is running with Swarm.ResourceMgr.Enabled") -func ResourceManager(cfg config.SwarmConfig, acceleratedDHT bool) interface{} { +func ResourceManager(cfg config.SwarmConfig) interface{} { return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, repo repo.Repo) (network.ResourceManager, Libp2pOpts, error) { var manager network.ResourceManager var opts Libp2pOpts @@ -52,7 +52,7 @@ func ResourceManager(cfg config.SwarmConfig, acceleratedDHT bool) interface{} { return nil, opts, fmt.Errorf("opening IPFS_PATH: %w", err) } - limits, err := createDefaultLimitConfig(cfg, acceleratedDHT) + limits, err := createDefaultLimitConfig(cfg) if err != nil { return nil, opts, err } @@ -513,7 +513,7 @@ func NetResetLimit(mgr network.ResourceManager, repo repo.Repo, scope string) (r return result, fmt.Errorf("reading config to reset limit: %w", err) } - defaults, err := createDefaultLimitConfig(cfg.Swarm, cfg.Experimental.AcceleratedDHTClient) + defaults, err := createDefaultLimitConfig(cfg.Swarm) if err != nil { return result, fmt.Errorf("creating default limit config: %w", err) } diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index 2c1f3d93a8c..84eedf7ed50 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -57,9 +57,6 @@ var noLimitIncrease = rcmgr.BaseLimitIncrease{ // - cfg.ResourceMgr.MaxFileDescriptors: This is the maximum number of file descriptors to allow libp2p to use. // libp2p's resource manager will prevent additional file descriptor consumption while this limit is hit. // If this value isn't specified, the maximum between 1/2 of system FD limit and 4096 is used. -// - Swarm.ConnMgr.HighWater: If a connection manager is specified, libp2p's resource manager -// will allow 2x more connections than the HighWater mark -// so the connection manager has "space and time" to close "least useful" connections. // // With these inputs defined, limits are created at the system, transient, and peer scopes. // Other scopes are ignored (by being set to infinity). @@ -89,7 +86,18 @@ var noLimitIncrease = rcmgr.BaseLimitIncrease{ // maxMemory, maxFD, or maxConns with Swarm.HighWater.ConnMgr. // 3. Power user - They specify all the limits they want set via Swarm.ResourceMgr.Limits // and we don't do any defaults/overrides. We pass that config blindly into libp2p resource manager. -func createDefaultLimitConfig(cfg config.SwarmConfig, acceleratedDHT bool) (rcmgr.LimitConfig, error) { +// +// Note that within libp2p. Swarm.ConnMgr settings have no impact on libp2p's resource manager limits. +// See https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/README.md#connmanager-vs-resource-manager +// and https://github.com/libp2p/go-libp2p/issues/1640 +// We also don't layer on extra logic in this function because SystemBaseLimit.Conns is already "bigEnough". +// There is headroom for the connection manager to apply any Swarm.ConnMgr.HighWater mark. +// We're keeping things simple by avoiding any interaction between libp2p's resource manager and connection manager. +// For example we don't set SystemBaseLimit.Conns to be related to Swarm.ConnMgr.HighWater. +// SystemBaseLimit.Conns is "bigEnough" and won't won't limit total connections. +// (We will limit SystemBaseLimit.ConnsInbound though.) +// The Swarm.ConnMgr can manage connections based on Swarm.ConnMgr.HighWater. +func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.LimitConfig, error) { maxMemoryDefaultString := humanize.Bytes(uint64(memory.TotalMemory()) / 8) maxMemoryString := cfg.ResourceMgr.MaxMemory.WithDefault(maxMemoryDefaultString) maxMemory, err := humanize.ParseBytes(maxMemoryString) @@ -217,12 +225,5 @@ func createDefaultLimitConfig(cfg config.SwarmConfig, acceleratedDHT bool) (rcmg defaultLimitConfig := scalingLimitConfig.Scale(int64(maxMemory), int(numFD)) - // If a high water mark is set (ignore when using accelerated DHT): - if cfg.ConnMgr.Type == "basic" && !acceleratedDHT { - // set the connection limit higher than high water mark so that the ConnMgr has "space and time" to close "least useful" connections. - defaultLimitConfig.System.Conns = 2 * cfg.ConnMgr.HighWater - log.Info("adjusted default resource manager System.Conns limits to match ConnMgr.HighWater value of %s", cfg.ConnMgr.HighWater) - } - return defaultLimitConfig, nil } From 4bff0420368680bd94a8a2ca2d9e560baf029c54 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Tue, 15 Nov 2022 17:52:07 +0100 Subject: [PATCH 05/16] Update core/node/libp2p/rcmgr_defaults.go Co-authored-by: Steve Loeppky --- core/node/libp2p/rcmgr_defaults.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index 84eedf7ed50..4b32fd921b3 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -141,14 +141,16 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.LimitConfig, error) }, TransientBaseLimit: rcmgr.BaseLimit{ - Streams: bigEnough, - StreamsInbound: rcmgr.DefaultLimits.TransientBaseLimit.StreamsInbound, - StreamsOutbound: bigEnough, + Memory: rcmgr.DefaultLimits.TransientBaseLimit.Memory, + FD: rcmgr.DefaultLimits.TransientBaseLimit.FD, + Conns: bigEnough, ConnsInbound: rcmgr.DefaultLimits.TransientBaseLimit.ConnsInbound, ConnsOutbound: bigEnough, - FD: rcmgr.DefaultLimits.TransientBaseLimit.FD, - Memory: rcmgr.DefaultLimits.TransientBaseLimit.Memory, + + Streams: bigEnough, + StreamsInbound: rcmgr.DefaultLimits.TransientBaseLimit.StreamsInbound, + StreamsOutbound: bigEnough, }, TransientLimitIncrease: rcmgr.BaseLimitIncrease{ From dfa631e841038f56f1c9161e0f4598cb361bd851 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Tue, 15 Nov 2022 18:04:37 +0100 Subject: [PATCH 06/16] Apply go fmt Signed-off-by: Antonio Navarro Perez --- core/node/libp2p/rcmgr_defaults.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index 4b32fd921b3..f05e1f4f3c2 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -141,13 +141,13 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.LimitConfig, error) }, TransientBaseLimit: rcmgr.BaseLimit{ - Memory: rcmgr.DefaultLimits.TransientBaseLimit.Memory, - FD: rcmgr.DefaultLimits.TransientBaseLimit.FD, - - Conns: bigEnough, - ConnsInbound: rcmgr.DefaultLimits.TransientBaseLimit.ConnsInbound, - ConnsOutbound: bigEnough, - + Memory: rcmgr.DefaultLimits.TransientBaseLimit.Memory, + FD: rcmgr.DefaultLimits.TransientBaseLimit.FD, + + Conns: bigEnough, + ConnsInbound: rcmgr.DefaultLimits.TransientBaseLimit.ConnsInbound, + ConnsOutbound: bigEnough, + Streams: bigEnough, StreamsInbound: rcmgr.DefaultLimits.TransientBaseLimit.StreamsInbound, StreamsOutbound: bigEnough, From f29640e0c8cc2bbad046145adcdeb77a5ff9acb5 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 11 Nov 2022 01:15:30 +0100 Subject: [PATCH 07/16] fix(config): skip nulls in ResourceMgr --- config/swarm.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/swarm.go b/config/swarm.go index 63119282772..b6cc9aa9a2b 100644 --- a/config/swarm.go +++ b/config/swarm.go @@ -144,8 +144,8 @@ type ResourceMgr struct { Enabled Flag `json:",omitempty"` Limits *rcmgr.LimitConfig `json:",omitempty"` - MaxMemory OptionalString `json:",omitempty"` - MaxFileDescriptors OptionalInteger `json:",omitempty"` + MaxMemory *OptionalString `json:",omitempty"` + MaxFileDescriptors *OptionalInteger `json:",omitempty"` // A list of multiaddrs that can bypass normal system limits (but are still // limited by the allowlist scope). Convenience config around From 65365192f754d18c00f2411e833b74ff0aee9f3d Mon Sep 17 00:00:00 2001 From: Lucas Molas Date: Tue, 26 Apr 2022 20:49:14 -0300 Subject: [PATCH 08/16] refactor(config): remove Swarm.ConnMgr defaults This moves defaults to Kubo code, cleaning up config. If value is in config, we assume it is an explicit choice made by user. Makes migrations easier. --- config/init.go | 12 ++++-------- config/profile.go | 10 +++++++--- config/swarm.go | 8 ++++---- core/node/groups.go | 39 +++++++++++++-------------------------- docs/changelogs/v0.17.md | 19 ++++++++++++++++++- docs/config.md | 22 ++++++++++++++-------- 6 files changed, 60 insertions(+), 50 deletions(-) diff --git a/config/init.go b/config/init.go index cc2351f1f4e..f86317369f5 100644 --- a/config/init.go +++ b/config/init.go @@ -79,14 +79,6 @@ func InitWithIdentity(identity Identity) (*Config, error) { Interval: "12h", Strategy: "all", }, - Swarm: SwarmConfig{ - ConnMgr: ConnMgr{ - LowWater: DefaultConnMgrLowWater, - HighWater: DefaultConnMgrHighWater, - GracePeriod: DefaultConnMgrGracePeriod.String(), - Type: "basic", - }, - }, Pinning: Pinning{ RemoteServices: map[string]RemotePinningService{}, }, @@ -114,6 +106,10 @@ const DefaultConnMgrLowWater = 600 // grace period const DefaultConnMgrGracePeriod = time.Second * 20 +// DefaultConnMgrType is the default value for the connection managers +// type. +const DefaultConnMgrType = "basic" + func addressesConfig() Addresses { return Addresses{ Swarm: []string{ diff --git a/config/profile.go b/config/profile.go index cbc7c976453..6748b5fb2b7 100644 --- a/config/profile.go +++ b/config/profile.go @@ -178,9 +178,13 @@ fetching may be degraded. c.AutoNAT.ServiceMode = AutoNATServiceDisabled c.Reprovider.Interval = "0" - c.Swarm.ConnMgr.LowWater = 20 - c.Swarm.ConnMgr.HighWater = 40 - c.Swarm.ConnMgr.GracePeriod = time.Minute.String() + lowWater := int64(20) + highWater := int64(40) + gracePeriod := time.Minute + c.Swarm.ConnMgr.Type = NewOptionalString("basic") + c.Swarm.ConnMgr.LowWater = &OptionalInteger{value: &lowWater} + c.Swarm.ConnMgr.HighWater = &OptionalInteger{value: &highWater} + c.Swarm.ConnMgr.GracePeriod = &OptionalDuration{&gracePeriod} return nil }, }, diff --git a/config/swarm.go b/config/swarm.go index b6cc9aa9a2b..d8fd17e946d 100644 --- a/config/swarm.go +++ b/config/swarm.go @@ -131,10 +131,10 @@ type Transports struct { // ConnMgr defines configuration options for the libp2p connection manager type ConnMgr struct { - Type string - LowWater int - HighWater int - GracePeriod string + Type *OptionalString `json:",omitempty"` + LowWater *OptionalInteger `json:",omitempty"` + HighWater *OptionalInteger `json:",omitempty"` + GracePeriod *OptionalDuration `json:",omitempty"` } // ResourceMgr defines configuration options for the libp2p Network Resource Manager diff --git a/core/node/groups.go b/core/node/groups.go index fca984650d9..5c576fc447f 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -38,33 +38,20 @@ var BaseLibP2P = fx.Options( ) func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { - // parse ConnMgr config - - grace := config.DefaultConnMgrGracePeriod - low := config.DefaultConnMgrLowWater - high := config.DefaultConnMgrHighWater - - connmgr := fx.Options() - - if cfg.Swarm.ConnMgr.Type != "none" { - switch cfg.Swarm.ConnMgr.Type { - case "": - // 'default' value is the basic connection manager - break - case "basic": - var err error - grace, err = time.ParseDuration(cfg.Swarm.ConnMgr.GracePeriod) - if err != nil { - return fx.Error(fmt.Errorf("parsing Swarm.ConnMgr.GracePeriod: %s", err)) - } - - low = cfg.Swarm.ConnMgr.LowWater - high = cfg.Swarm.ConnMgr.HighWater - default: - return fx.Error(fmt.Errorf("unrecognized ConnMgr.Type: %q", cfg.Swarm.ConnMgr.Type)) - } - + var connmgr fx.Option + + // set connmgr based on Swarm.ConnMgr.Type + connMgrType := cfg.Swarm.ConnMgr.Type.WithDefault(config.DefaultConnMgrType) + switch connMgrType { + case "none": + connmgr = fx.Options() // noop + case "", "basic": + grace := cfg.Swarm.ConnMgr.GracePeriod.WithDefault(config.DefaultConnMgrGracePeriod) + low := int(cfg.Swarm.ConnMgr.LowWater.WithDefault(config.DefaultConnMgrLowWater)) + high := int(cfg.Swarm.ConnMgr.HighWater.WithDefault(config.DefaultConnMgrHighWater)) connmgr = fx.Provide(libp2p.ConnectionManager(low, high, grace)) + default: + return fx.Error(fmt.Errorf("unrecognized Swarm.ConnMgr.Type: %q", connMgrType)) } // parse PubSub config diff --git a/docs/changelogs/v0.17.md b/docs/changelogs/v0.17.md index efe0099395b..941fd419f9d 100644 --- a/docs/changelogs/v0.17.md +++ b/docs/changelogs/v0.17.md @@ -9,8 +9,8 @@ Below is an outline of all that is in this release, so you get a sense of all th - [Kubo changelog v0.17](#kubo-changelog-v017) - [v0.17.0](#v0170) - [Overview](#overview) - - [TOC](#toc) - [🔦 Highlights](#-highlights) + - [Implicit connection manager limits](#implicit-connection-manager-limits) - [TAR Response Format on Gateways](#tar-response-format-on-gateways) - [Changelog](#changelog) - [Contributors](#contributors) @@ -19,6 +19,23 @@ Below is an outline of all that is in this release, so you get a sense of all th +#### Implicit connection manager limits + +Starting with this release, `ipfs init` will no longer store the default +[Connection Manager](https://github.com/ipfs/kubo/blob/master/docs/config.md#swarmconnmgr) +limits in the user config under `Swarm.ConnMgr`. + +Users are still free to use this setting to set custom values, but for most use +cases, the defaults provided with the latest Kubo release should be sufficient. + +To remove any custom limits and switch to the implicit defaults managed by Kubo: + +```console +$ ipfs config --json Swarm.ConnMgr '{}' +``` + +We will be adjusting defaults in the future releases. + #### TAR Response Format on Gateways Implemented [IPIP-288](https://github.com/ipfs/specs/pull/288) which adds diff --git a/docs/config.md b/docs/config.md index 58d62a43322..784a42d730e 100644 --- a/docs/config.md +++ b/docs/config.md @@ -243,9 +243,15 @@ documented in `ipfs config profile --help`. - `lowpower` - Reduces daemon overhead on the system. May affect node + Reduces daemon overhead on the system. Affects node functionality - performance of content discovery and data - fetching may be degraded. + fetching may be degraded. Local data won't be announced on routing systems like DHT. + + - `Swarm.ConnMgr` set to maintain minimum number of p2p connections at a time. + - Disables [`Reprovider`](#reprovider) service → no CID will be announced on DHT and other routing systems(!) + - Disables AutoNAT. + + Use this profile with caution. ## Types @@ -1695,7 +1701,8 @@ be configured to keep. Kubo currently supports two connection managers: * none: never close idle connections. * basic: the default connection manager. -Default: basic +By default, this section is empty and the implicit defaults defined below +are used. #### `Swarm.ConnMgr.Type` @@ -1704,8 +1711,7 @@ management) and `"basic"`. Default: "basic". -Type: `string` (when unset or `""`, the default connection manager is applied -and all `ConnMgr` fields are ignored). +Type: `optionalString` (default when unset or empty) #### Basic Connection Manager @@ -1744,7 +1750,7 @@ trim down to. Default: `600` -Type: `integer` +Type: `optionalInteger` ##### `Swarm.ConnMgr.HighWater` @@ -1754,7 +1760,7 @@ towards this limit. Default: `900` -Type: `integer` +Type: `optionalInteger` ##### `Swarm.ConnMgr.GracePeriod` @@ -1763,7 +1769,7 @@ by the connection manager. Default: `"20s"` -Type: `duration` +Type: `optionalDuration` ### `Swarm.ResourceMgr` From 13b9a62ae5d6a87b15f32b09d6e0b604e4246378 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 15 Nov 2022 20:17:00 +0100 Subject: [PATCH 09/16] docs: document /wss fixes in 0.17 --- docs/changelogs/v0.17.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/changelogs/v0.17.md b/docs/changelogs/v0.17.md index 941fd419f9d..8cab7499126 100644 --- a/docs/changelogs/v0.17.md +++ b/docs/changelogs/v0.17.md @@ -12,6 +12,7 @@ Below is an outline of all that is in this release, so you get a sense of all th - [🔦 Highlights](#-highlights) - [Implicit connection manager limits](#implicit-connection-manager-limits) - [TAR Response Format on Gateways](#tar-response-format-on-gateways) + - [Dialling `/wss` peer behind a reverse proxy](#dialling-wss-peer-behind-a-reverse-proxy) - [Changelog](#changelog) - [Contributors](#contributors) @@ -54,6 +55,14 @@ bafybeigccimv3zqm5g4jt363faybagywkvqbrismoquogimy7kvz2sj7sq/1 - Barrel - Part 1 bafybeigccimv3zqm5g4jt363faybagywkvqbrismoquogimy7kvz2sj7sq/1 - Barrel - Part 1.png ``` +#### Dialling `/wss` peer behind a reverse proxy + +This release resolves a regression introduced in Kubo 0.16, making it possible +again to connect to a peer over a WebSockets endpoint (`/wss`) that is +deployed behind a reverse proxy. + +More details in [go-libp2p release notes](https://github.com/libp2p/go-libp2p/releases/tag/v0.23.3). + ### Changelog From db3d1cd8e14ef455611a44a6468ccb0103a2cf02 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 11 Nov 2022 00:05:02 +0100 Subject: [PATCH 10/16] fix(docs): typo --- docs/config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/config.md b/docs/config.md index 784a42d730e..b285ec1eb52 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1835,8 +1835,8 @@ struct from [go-libp2p-resource-manager](https://github.com/libp2p/go-libp2p/tre Current resource usage and a list of services, protocols, and peers can be obtained via `ipfs swarm stats --help` -It is also possible to adjust some runtime limits via `ipfs stats limit --help`. -Changes made via `stats limit` are persisted in `Swarm.ResourceMgr.Limits`. +It is also possible to adjust some runtime limits via `ipfs swarm limit --help`. +Changes made via `ipfs swarm limit` are persisted in `Swarm.ResourceMgr.Limits`. Default: `{}` (use the safe implicit defaults) From 1127a15aebc0448c3c0ff8f6eaa6d34da2db644c Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Mon, 14 Nov 2022 13:03:46 +0100 Subject: [PATCH 11/16] fix: update go-unixfs lib to v0.4.1 Signed-off-by: Antonio Navarro Perez --- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 6eac119b0df..b7398dbaa12 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -103,7 +103,7 @@ require ( github.com/ipfs/go-namesys v0.5.0 // indirect github.com/ipfs/go-path v0.3.0 // indirect github.com/ipfs/go-peertaskqueue v0.7.1 // indirect - github.com/ipfs/go-unixfs v0.4.0 // indirect + github.com/ipfs/go-unixfs v0.4.1 // indirect github.com/ipfs/go-unixfsnode v1.4.0 // indirect github.com/ipfs/go-verifcid v0.0.2 // indirect github.com/ipld/edelweiss v0.2.0 // indirect diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index b72fece84d6..170376b10e1 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -648,8 +648,8 @@ github.com/ipfs/go-peertaskqueue v0.7.1/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68 github.com/ipfs/go-pinning-service-http-client v0.1.2/go.mod h1:6wd5mjYhXJTiWU8b4RSWPpWdlzE5/csoXV0dWWMjun4= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= -github.com/ipfs/go-unixfs v0.4.0 h1:qSyyxfB/OiDdWHYiSbyaqKC7zfSE/TFL0QdwkRjBm20= -github.com/ipfs/go-unixfs v0.4.0/go.mod h1:I7Nqtm06HgOOd+setAoCU6rf/HgVFHE+peeNuOv/5+g= +github.com/ipfs/go-unixfs v0.4.1 h1:nmJFKvF+khK03PIWyCxxydD/nkQX315NZDcgvRqMXf0= +github.com/ipfs/go-unixfs v0.4.1/go.mod h1:2SUDFhUSzrcL408B1qpIkJJ5HznnyTzweViPXUAvkNg= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= github.com/ipfs/go-unixfsnode v1.4.0 h1:9BUxHBXrbNi8mWHc6j+5C580WJqtVw9uoeEKn4tMhwA= github.com/ipfs/go-unixfsnode v1.4.0/go.mod h1:qc7YFFZ8tABc58p62HnIYbUMwj9chhUuFWmxSokfePo= diff --git a/go.mod b/go.mod index 57f83d205fb..405284f4986 100644 --- a/go.mod +++ b/go.mod @@ -58,7 +58,7 @@ require ( github.com/ipfs/go-namesys v0.5.0 github.com/ipfs/go-path v0.3.0 github.com/ipfs/go-pinning-service-http-client v0.1.2 - github.com/ipfs/go-unixfs v0.4.0 + github.com/ipfs/go-unixfs v0.4.1 github.com/ipfs/go-unixfsnode v1.4.0 github.com/ipfs/go-verifcid v0.0.2 github.com/ipfs/interface-go-ipfs-core v0.7.0 diff --git a/go.sum b/go.sum index fac4bfe11b1..ef0441f6c3a 100644 --- a/go.sum +++ b/go.sum @@ -638,8 +638,8 @@ github.com/ipfs/go-pinning-service-http-client v0.1.2 h1:jdr7KelhL9gNHTU8jbqPMwI github.com/ipfs/go-pinning-service-http-client v0.1.2/go.mod h1:6wd5mjYhXJTiWU8b4RSWPpWdlzE5/csoXV0dWWMjun4= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= -github.com/ipfs/go-unixfs v0.4.0 h1:qSyyxfB/OiDdWHYiSbyaqKC7zfSE/TFL0QdwkRjBm20= -github.com/ipfs/go-unixfs v0.4.0/go.mod h1:I7Nqtm06HgOOd+setAoCU6rf/HgVFHE+peeNuOv/5+g= +github.com/ipfs/go-unixfs v0.4.1 h1:nmJFKvF+khK03PIWyCxxydD/nkQX315NZDcgvRqMXf0= +github.com/ipfs/go-unixfs v0.4.1/go.mod h1:2SUDFhUSzrcL408B1qpIkJJ5HznnyTzweViPXUAvkNg= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= github.com/ipfs/go-unixfsnode v1.4.0 h1:9BUxHBXrbNi8mWHc6j+5C580WJqtVw9uoeEKn4tMhwA= github.com/ipfs/go-unixfsnode v1.4.0/go.mod h1:qc7YFFZ8tABc58p62HnIYbUMwj9chhUuFWmxSokfePo= From 9de9c12ef4a295bc450077e466468eb995578945 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 15 Nov 2022 18:16:24 +0100 Subject: [PATCH 12/16] chore(ci): bigger box for webui and interop These two are on par with sharness, and webui became flaky. Flakiness will be addressed upstream, but this should decrease how often it occurs + make CI faster (making sharness the longest one again) --- .circleci/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/main.yml b/.circleci/main.yml index 86684a5d0cc..08e176656f6 100644 --- a/.circleci/main.yml +++ b/.circleci/main.yml @@ -224,7 +224,7 @@ jobs: docker: - image: cimg/go:1.19.1-node parallelism: 4 - resource_class: large + resource_class: 2xlarge+ steps: - *make_out_dirs - attach_workspace: @@ -324,6 +324,7 @@ jobs: - ~/.cache/go-build/ ipfs-webui: executor: node-browsers + resource_class: 2xlarge+ steps: - *make_out_dirs - attach_workspace: From 83034d840cd3ecfed5084835490a3088fc3e230b Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Wed, 16 Nov 2022 10:26:59 +0000 Subject: [PATCH 13/16] Doc improvements and changelog for resource manager (#9413) Co-authored-by: Antonio Navarro Perez --- core/node/libp2p/rcmgr.go | 12 ++-- core/node/libp2p/rcmgr_defaults.go | 56 +---------------- docs/changelogs/v0.17.md | 23 +++++++ docs/config.md | 96 +++++++++++++++++++++++++----- 4 files changed, 115 insertions(+), 72 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 49c9d382399..35894dc7234 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -52,18 +52,22 @@ func ResourceManager(cfg config.SwarmConfig) interface{} { return nil, opts, fmt.Errorf("opening IPFS_PATH: %w", err) } - limits, err := createDefaultLimitConfig(cfg) + limitConfig, err := createDefaultLimitConfig(cfg) if err != nil { return nil, opts, err } + // The logic for defaults and overriding with specified SwarmConfig.ResourceMgr.Limits + // is documented in docs/config.md. + // Any changes here should be reflected there. if cfg.ResourceMgr.Limits != nil { l := *cfg.ResourceMgr.Limits - l.Apply(limits) - limits = l + // This effectively overrides the computed default LimitConfig with any vlues from cfg.ResourceMgr.Limits + l.Apply(limitConfig) + limitConfig = l } - limiter := rcmgr.NewFixedLimiter(limits) + limiter := rcmgr.NewFixedLimiter(limitConfig) str, err := rcmgrObs.NewStatsTraceReporter() if err != nil { diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index f05e1f4f3c2..3cee4c50c47 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -44,59 +44,8 @@ var noLimitIncrease = rcmgr.BaseLimitIncrease{ // This file defines implicit limit defaults used when Swarm.ResourceMgr.Enabled // createDefaultLimitConfig creates LimitConfig to pass to libp2p's resource manager. -// libp2p's resource manager provides tremendous flexibility but also adds a lot of complexity. -// The intent of the default config here is to provide good defaults, -// and where the defaults aren't good enough, -// to expose a good set of higher-level "knobs" to users to satisfy most use cases -// without requiring users to wade into all the intricacies of libp2p's resource manager. -// -// The inputs one can specify in SwarmConfig are: -// - cfg.ResourceMgr.MaxMemory: This is the max amount of memory in bytes to allow libp2p to use. -// libp2p's resource manager will prevent additional resource creation while this limit is hit. -// If this value isn't specified, 1/8th of the total system memory is used. -// - cfg.ResourceMgr.MaxFileDescriptors: This is the maximum number of file descriptors to allow libp2p to use. -// libp2p's resource manager will prevent additional file descriptor consumption while this limit is hit. -// If this value isn't specified, the maximum between 1/2 of system FD limit and 4096 is used. -// -// With these inputs defined, limits are created at the system, transient, and peer scopes. -// Other scopes are ignored (by being set to infinity). -// The reason these scopes are chosen is because: -// - system - This gives us the coarse-grained control we want so we can reason about the system as a whole. -// It is the backstop, and allows us to reason about resource consumption more easily -// since don't have think about the interaction of many other scopes. -// - transient - Limiting connections that are in process of being established provides backpressure so not too much work queues up. -// - peer - The peer scope doesn't protect us against intentional DoS attacks. -// It's just as easy for an attacker to send 100 requests/second with 1 peerId vs. 10 requests/second with 10 peers. -// We are reliant on the system scope for protection here in the malicious case. -// The reason for having a peer scope is to protect against unintentional DoS attacks -// (e.g., bug in a peer which is causing it to "misbehave"). -// In the unintional case, we want to make sure a "misbehaving" node doesn't consume more resources than necessary. -// -// Within these scopes, limits are just set on memory, FD, and inbound connections/streams. -// Limits are set based on the inputs above. -// We trust this node to behave properly and thus ignore outbound connection/stream limits. -// We apply any limits that libp2p has for its protocols/services -// since we assume libp2p knows best here. -// -// This leaves 3 levels of resource management protection: -// 1. The user who does nothing and uses defaults - In this case they get some sane defaults -// based on the amount of memory and file descriptors their system has. -// This should protect the node from many attacks. -// 2. Slightly more advanced user - They can tweak the above by passing in config on -// maxMemory, maxFD, or maxConns with Swarm.HighWater.ConnMgr. -// 3. Power user - They specify all the limits they want set via Swarm.ResourceMgr.Limits -// and we don't do any defaults/overrides. We pass that config blindly into libp2p resource manager. -// -// Note that within libp2p. Swarm.ConnMgr settings have no impact on libp2p's resource manager limits. -// See https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/README.md#connmanager-vs-resource-manager -// and https://github.com/libp2p/go-libp2p/issues/1640 -// We also don't layer on extra logic in this function because SystemBaseLimit.Conns is already "bigEnough". -// There is headroom for the connection manager to apply any Swarm.ConnMgr.HighWater mark. -// We're keeping things simple by avoiding any interaction between libp2p's resource manager and connection manager. -// For example we don't set SystemBaseLimit.Conns to be related to Swarm.ConnMgr.HighWater. -// SystemBaseLimit.Conns is "bigEnough" and won't won't limit total connections. -// (We will limit SystemBaseLimit.ConnsInbound though.) -// The Swarm.ConnMgr can manage connections based on Swarm.ConnMgr.HighWater. +// The defaults follow the documentation in docs/config.md. +// Any changes in the logic here should be reflected there. func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.LimitConfig, error) { maxMemoryDefaultString := humanize.Bytes(uint64(memory.TotalMemory()) / 8) maxMemoryString := cfg.ResourceMgr.MaxMemory.WithDefault(maxMemoryDefaultString) @@ -113,7 +62,6 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.LimitConfig, error) FD: int(numFD), // By default, we just limit connections on the inbound side. - // Note that the limit gets adjusted below if "cfg.ConnMgr.HighWater" is set. Conns: bigEnough, ConnsInbound: rcmgr.DefaultLimits.SystemBaseLimit.ConnsInbound, // same as libp2p default ConnsOutbound: bigEnough, diff --git a/docs/changelogs/v0.17.md b/docs/changelogs/v0.17.md index 8cab7499126..b6a562c0cac 100644 --- a/docs/changelogs/v0.17.md +++ b/docs/changelogs/v0.17.md @@ -10,6 +10,7 @@ Below is an outline of all that is in this release, so you get a sense of all th - [v0.17.0](#v0170) - [Overview](#overview) - [🔦 Highlights](#-highlights) + - [libp2p resource management enabled by default](#libp2p-resource-management-enabled-by-default) - [Implicit connection manager limits](#implicit-connection-manager-limits) - [TAR Response Format on Gateways](#tar-response-format-on-gateways) - [Dialling `/wss` peer behind a reverse proxy](#dialling-wss-peer-behind-a-reverse-proxy) @@ -20,6 +21,28 @@ Below is an outline of all that is in this release, so you get a sense of all th +#### libp2p resource management enabled by default + +To help protect nodes from DoS (resource exhaustion) and eclipse attacks, +go-libp2p released a [Network Resource Manager](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager) with a host of improvements throughout 2022. + +Kubo first [exposed this functionality in Kubo 0.13](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.13.md#-libp2p-network-resource-manager-swarmresourcemgr), +but it was disabled by default. + +The resource manager is now enabled by default to protect nodes. +The defaults balance providing protection from various attacks while still enabling normal usecases to work as expected. + +If you want to adjust the defaults, then you can: +1. bound the amount of memory and file descriptors that libp2p will use with [Swarm.ResourceMgr.MaxMemory](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgrmaxmemory) +and [Swarm.ResourceMgr.MaxFileDescriptors](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgrmaxfiledescriptors) and/or +2. override any specific resource scopes/limits with [Swarm.ResourceMgr.Limits](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgrlimits) + +See [Swarm.ResourceMgr](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgr) for +1. what limits are set by default, +2. example override configuration, +3. how to access prometheus metrics and view grafana dashboards of resource usage, and +4. how to set explicit "allow lists" to protect against eclipse attacks. + #### Implicit connection manager limits Starting with this release, `ipfs init` will no longer store the default diff --git a/docs/config.md b/docs/config.md index b285ec1eb52..5027b67b7c2 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1773,30 +1773,78 @@ Type: `optionalDuration` ### `Swarm.ResourceMgr` -The [libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p-resource-manager#readme) allows setting limits per a scope, +The [libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#readme) allows setting limits per [Resource Scope](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#resource-scopes), and tracking recource usage over time. -#### `Swarm.ResourceMgr.Enabled` +##### Levels of Configuration + +libp2p's resource manager provides tremendous flexibility but also adds a lot of complexity. +There are these levels of limit configuration for resource management protection: +1. "The user who does nothing" - In this case they get some sane defaults discussed below + based on the amount of memory and file descriptors their system has. + This should protect the node from many attacks. +2. "Slightly more advanced user" - They can tweak the default limits discussed below. + Where the defaults aren't good enough, a good set of higher-level "knobs" are exposed to satisfy most use cases + without requiring users to wade into all the intricacies of libp2p's resource manager. + The "knobs"/inputs are `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` as described below. +3. "Power user" - They specify all the default limits from below they want override via `Swarm.ResourceMgr.Limits`; + +##### Default Limits + +With these inputs defined, [resource manager limits](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#limits) are created at the +[system](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#the-system-scope), +[transient](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#the-transient-scope), +and [peer](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#peer-scopes) scopes. +Other scopes are ignored (by being set to "~infinity". + +The reason these scopes are chosen is because: +- system - This gives us the coarse-grained control we want so we can reason about the system as a whole. + It is the backstop, and allows us to reason about resource consumption more easily + since don't have think about the interaction of many other scopes. +- transient - Limiting connections that are in process of being established provides backpressure so not too much work queues up. +- peer - The peer scope doesn't protect us against intentional DoS attacks. + It's just as easy for an attacker to send 100 requests/second with 1 peerId vs. 10 requests/second with 10 peers. + We are reliant on the system scope for protection here in the malicious case. + The reason for having a peer scope is to protect against unintentional DoS attacks + (e.g., bug in a peer which is causing it to "misbehave"). + In the unintional case, we want to make sure a "misbehaving" node doesn't consume more resources than necessary. + +Within these scopes, limits are just set on +[memory](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#memory), +[file descriptors (FD)](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#file-descriptors), [*inbound* connections](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#connections), +and [*inbound* streams](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#streams). +Limits are set based on the inputs above. +We trust this node to behave properly and thus don't limit *outbound* connection/stream limits. +We apply any limits that libp2p has for its protocols/services +since we assume libp2p knows best here. + +** libp2p resource monitoring ** +For [monitoring libp2p resource usage](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#monitoring), +various `*rcmgr_*` metrics can be accessed as the prometheus endpoint at `{Addresses.API}/debug/metrics/prometheus` (default: `http://127.0.0.1:5001/debug/metrics/prometheus`). +There are also [pre-built Grafana dashboards](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager/obs/grafana-dashboards) that can be added to a Grafana instance. -Enables the libp2p Network Resource Manager and auguments the default limits -using user-defined ones in `Swarm.ResourceMgr.Limits` (if present). +#### `Swarm.ResourceMgr.Enabled` -Various `*rcmgr_*` metrics can be accessed as the prometheus endpoint at `{Addresses.API}/debug/metrics/prometheus` (default: `http://127.0.0.1:5001/debug/metrics/prometheus`) +Enables the libp2p Resource Manager using limits based on the defaults and/or other configuration as discussed above. Default: `true` - Type: `flag` #### `Swarm.ResourceMgr.MaxMemory` -The maximum amount of memory that the libp2p resource manager will allow. +This is the max amount of memory to allow libp2p to use. +libp2p's resource manager will prevent additional resource creation while this limit is reached. +This value is also used to scale the limit on various resources at various scopes +when the default limits (discuseed above) are used. +For example, increasing this value will increase the default limit for incoming connections. Default: `[TOTAL_SYSTEM_MEMORY]/8` Type: `optionalBytes` #### `Swarm.ResourceMgr.MaxFileDescriptors` -Define the maximum number of file descriptors that libp2p can use. +This is the maximum number of file descriptors to allow libp2p to use. +libp2p's resource manager will prevent additional file descriptor consumption while this limit is reached. This param is ignored on Windows. @@ -1807,21 +1855,26 @@ Type: `optionalInteger` Map of resource limits [per scope](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#resource-scopes). -The map supports fields from [`ScalingLimitConfig`](https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/limit_defaults.go#L21-L59) -struct from [go-libp2p-resource-manager](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#readme). +The map supports fields from the [`LimitConfig` struct](https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/limit_defaults.go#L111). +[`BaseLimit`s](https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/limit.go#L89) can be set for any scope, and within the `BaseLimit`, all limit s are optional. + +The `Swarm.ResourceMgr.Limits` override the default limits described above. +Any override `BaseLimits` or limit s from `Swarm.ResourceMgr.Limits` +that aren't specified will use the default limits. + +Example #1: setting limits for a specific scope ```json { "Swarm": { "ResourceMgr": { - "Enabled": true, "Limits": { "System": { + "Memory": 1073741824, + "FD": 512, "Conns": 1024, "ConnsInbound": 256, "ConnsOutbound": 1024, - "FD": 512, - "Memory": 1073741824, "Streams": 16384, "StreamsInbound": 4096, "StreamsOutbound": 16384 @@ -1832,13 +1885,28 @@ struct from [go-libp2p-resource-manager](https://github.com/libp2p/go-libp2p/tre } ``` +Example #2: setting a specific limit +```json +{ + "Swarm": { + "ResourceMgr": { + "Limits": { + "Transient": { + "ConnsOutbound": 256, + } + } + } + } +} +``` + Current resource usage and a list of services, protocols, and peers can be obtained via `ipfs swarm stats --help` It is also possible to adjust some runtime limits via `ipfs swarm limit --help`. Changes made via `ipfs swarm limit` are persisted in `Swarm.ResourceMgr.Limits`. -Default: `{}` (use the safe implicit defaults) +Default: `{}` (use the safe implicit defaults described above) Type: `object[string->object]` From 9246cdaf9c6230ba087016991a92bea9ddef73ff Mon Sep 17 00:00:00 2001 From: galargh Date: Wed, 16 Nov 2022 13:17:22 +0100 Subject: [PATCH 14/16] chore: bump version to v0.17.0-rc2 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index d03126e547c..025c110d56d 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.17.0-rc1" +const CurrentVersionNumber = "0.17.0-rc2" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From baafe9d2cac8b721201b0ee731142036db13b207 Mon Sep 17 00:00:00 2001 From: galargh Date: Tue, 22 Nov 2022 13:03:15 +0100 Subject: [PATCH 15/16] chore: bump version to v0.17.0 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 025c110d56d..adc94710436 100644 --- a/version.go +++ b/version.go @@ -11,7 +11,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.17.0-rc2" +const CurrentVersionNumber = "0.17.0" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From d007b2ae38955d7beb7441ce4600c8683175b9ce Mon Sep 17 00:00:00 2001 From: galargh Date: Tue, 22 Nov 2022 13:20:20 +0100 Subject: [PATCH 16/16] docs: udpate changelog --- docs/changelogs/v0.17.md | 137 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 127 insertions(+), 10 deletions(-) diff --git a/docs/changelogs/v0.17.md b/docs/changelogs/v0.17.md index b6a562c0cac..4d4bde3c170 100644 --- a/docs/changelogs/v0.17.md +++ b/docs/changelogs/v0.17.md @@ -23,25 +23,25 @@ Below is an outline of all that is in this release, so you get a sense of all th #### libp2p resource management enabled by default -To help protect nodes from DoS (resource exhaustion) and eclipse attacks, -go-libp2p released a [Network Resource Manager](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager) with a host of improvements throughout 2022. +To help protect nodes from DoS (resource exhaustion) and eclipse attacks, +go-libp2p released a [Network Resource Manager](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager) with a host of improvements throughout 2022. -Kubo first [exposed this functionality in Kubo 0.13](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.13.md#-libp2p-network-resource-manager-swarmresourcemgr), +Kubo first [exposed this functionality in Kubo 0.13](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.13.md#-libp2p-network-resource-manager-swarmresourcemgr), but it was disabled by default. -The resource manager is now enabled by default to protect nodes. +The resource manager is now enabled by default to protect nodes. The defaults balance providing protection from various attacks while still enabling normal usecases to work as expected. If you want to adjust the defaults, then you can: -1. bound the amount of memory and file descriptors that libp2p will use with [Swarm.ResourceMgr.MaxMemory](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgrmaxmemory) +1. bound the amount of memory and file descriptors that libp2p will use with [Swarm.ResourceMgr.MaxMemory](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgrmaxmemory) and [Swarm.ResourceMgr.MaxFileDescriptors](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgrmaxfiledescriptors) and/or 2. override any specific resource scopes/limits with [Swarm.ResourceMgr.Limits](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgrlimits) See [Swarm.ResourceMgr](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgr) for 1. what limits are set by default, -2. example override configuration, -3. how to access prometheus metrics and view grafana dashboards of resource usage, and -4. how to set explicit "allow lists" to protect against eclipse attacks. +2. example override configuration, +3. how to access prometheus metrics and view grafana dashboards of resource usage, and +4. how to set explicit "allow lists" to protect against eclipse attacks. #### Implicit connection manager limits @@ -88,8 +88,125 @@ More details in [go-libp2p release notes](https://github.com/libp2p/go-libp2p/re ### Changelog - +
Full Changelog + +- github.com/ipfs/kubo: + - chore: bump version to v0.17.0 ([ipfs/kubo#9427](https://github.com/ipfs/kubo/pull/9427)) + - chore: bump version to v0.17.0-rc2 ([ipfs/kubo#9414](https://github.com/ipfs/kubo/pull/9414)) + - Doc improvements and changelog for resource manager (#9413) ([ipfs/kubo#9413](https://github.com/ipfs/kubo/pull/9413)) + - fix(docs): typo + - docs: document /wss fixes in 0.17 + - refactor(config): remove Swarm.ConnMgr defaults + - fix(config): skip nulls in ResourceMgr + - Apply go fmt + - Update core/node/libp2p/rcmgr_defaults.go + - Remove limitation by HighWater param. + - Fix RM errors when acceleratedDHT is active + - docs: Deprecate Reframe on docs. (#9401) ([ipfs/kubo#9401](https://github.com/ipfs/kubo/pull/9401)) + - chore: bump version to v0.17.0-rc1 ([ipfs/kubo#9394](https://github.com/ipfs/kubo/pull/9394)) + - feat: Improve ResourceManager UX (#9338) ([ipfs/kubo#9338](https://github.com/ipfs/kubo/pull/9338)) + - feat: ipfs-webui 2.20.0 + - docs: note log tail is broken (#9383) ([ipfs/kubo#9383](https://github.com/ipfs/kubo/pull/9383)) + - feat(gateway): TAR response format (#9029) ([ipfs/kubo#9029](https://github.com/ipfs/kubo/pull/9029)) + - fix: error when using huge json limit file + - chore: go-multicodec v0.7.0 + - fix: remove old unused buggy coredag code + - feat: Add command line completion for fish + - chore: delete snap configuration ([ipfs/kubo#9352](https://github.com/ipfs/kubo/pull/9352)) + - docs: update scoop package + - docs: init release issue template improvement process v0.16.0 ([ipfs/kubo#9283](https://github.com/ipfs/kubo/pull/9283)) + - feat: add delegated routing metrics (#9354) ([ipfs/kubo#9354](https://github.com/ipfs/kubo/pull/9354)) + - chore: create v0.17.md changelog ([ipfs/kubo#9353](https://github.com/ipfs/kubo/pull/9353)) + - docs: pin remote arg + - feat: webui@v2.19.0 + - test(car): export/import of (dag-)cbor/json codecs + - add refs local alias repo ls (#9320) ([ipfs/kubo#9320](https://github.com/ipfs/kubo/pull/9320)) + - docs(cmds): Clarify block fetching of refs endpoint. + - chore(cmds): dag import: use ipld legacy decode ([ipfs/kubo#9219](https://github.com/ipfs/kubo/pull/9219)) + - fix ipfs swarm peering crash in offline mode (#9261) ([ipfs/kubo#9261](https://github.com/ipfs/kubo/pull/9261)) + - feat: remove provider delay interval in bitswap (#9053) ([ipfs/kubo#9053](https://github.com/ipfs/kubo/pull/9053)) + - feat: --reset flag on swarm limit command (#9310) ([ipfs/kubo#9310](https://github.com/ipfs/kubo/pull/9310)) + - fix: add InlineDNSLink flag to PublicGateways config (#9328) ([ipfs/kubo#9328](https://github.com/ipfs/kubo/pull/9328)) + - docs: Fix typo and grammar in README + - ci: add stylecheck to golangci-lint (#9334) ([ipfs/kubo#9334](https://github.com/ipfs/kubo/pull/9334)) + - Fix: `swarm stats all` command + - Merge release v0.16.0 back into master ([ipfs/kubo#9324](https://github.com/ipfs/kubo/pull/9324)) + - fix: Set default Methods value to nil + - docs: add WebTransport docs ([ipfs/kubo#9314](https://github.com/ipfs/kubo/pull/9314)) + - chore: bump version to 0.17.0-dev +- github.com/ipfs/go-delegated-routing (v0.6.0 -> v0.7.0): + - Release v0.7.0 + - feat: add latency & count metrics for content routing client (#59) ([ipfs/go-delegated-routing#59](https://github.com/ipfs/go-delegated-routing/pull/59)) + - docs: add basic readme ([ipfs/go-delegated-routing#57](https://github.com/ipfs/go-delegated-routing/pull/57)) + - sync: update CI config files ([ipfs/go-delegated-routing#40](https://github.com/ipfs/go-delegated-routing/pull/40)) + - added link to reframe blog post (#54) ([ipfs/go-delegated-routing#54](https://github.com/ipfs/go-delegated-routing/pull/54)) +- github.com/ipfs/go-ipfs-files (v0.1.1 -> v0.2.0): + - Release v0.2.0 + - fix: error when TAR has files outside of root (#56) ([ipfs/go-ipfs-files#56](https://github.com/ipfs/go-ipfs-files/pull/56)) + - sync: update CI config files ([ipfs/go-ipfs-files#55](https://github.com/ipfs/go-ipfs-files/pull/55)) + - chore(Directory): add DirIterator API restriction: iterate only once +- github.com/ipfs/go-unixfs (v0.4.0 -> v0.4.1): + - Update version.json + - Fix: panic when childer is nil (#127) ([ipfs/go-unixfs#127](https://github.com/ipfs/go-unixfs/pull/127)) + - sync: update CI config files (#125) ([ipfs/go-unixfs#125](https://github.com/ipfs/go-unixfs/pull/125)) +- github.com/ipld/go-ipld-prime (v0.18.0 -> v0.19.0): + - Prepare v0.19.0 + - fix: correct json codec links & bytes handling + - test(basicnode): increase test coverage for int and map types (#454) ([ipld/go-ipld-prime#454](https://github.com/ipld/go-ipld-prime/pull/454)) + - fix: remove reliance on ioutil + - run gofmt -s + - bump go.mod to Go 1.18 and run go fix + - feat: add kinded union to gendemo +- github.com/libp2p/go-libp2p (v0.23.2 -> v0.23.4): + - Release v0.23.4 (#1864) ([libp2p/go-libp2p#1864](https://github.com/libp2p/go-libp2p/pull/1864)) + - release v0.23.3 + - websocket: set the HTTP host header in WSS +- github.com/libp2p/go-netroute (v0.2.0 -> v0.2.1): + - v0.2.1 ([libp2p/go-netroute#27](https://github.com/libp2p/go-netroute/pull/27)) + - fix(phys-addr-length): fix physical address length mismatch ([libp2p/go-netroute#29](https://github.com/libp2p/go-netroute/pull/29)) + - compare priority if route rule's dst mask is same size + - compare priority if route rule's dst mask is same size + - sync: update CI config files (#24) ([libp2p/go-netroute#24](https://github.com/libp2p/go-netroute/pull/24)) +- github.com/marten-seemann/qpack (v0.2.1 -> v0.3.0): + - update to Ginkgo v2 (#30) ([marten-seemann/qpack#30](https://github.com/marten-seemann/qpack/pull/30)) + - return write error when encoding header fields (#28) ([marten-seemann/qpack#28](https://github.com/marten-seemann/qpack/pull/28)) + - update Go versions (#29) ([marten-seemann/qpack#29](https://github.com/marten-seemann/qpack/pull/29)) + - remove CircleCI build status from README + - add link to QPACK RFC to README + - remove build constraint from fuzzer ([marten-seemann/qpack#24](https://github.com/marten-seemann/qpack/pull/24)) +- github.com/multiformats/go-multicodec (v0.6.0 -> v0.7.0): + - feat: update ./multicodec/table.csv ([multiformats/go-multicodec#71](https://github.com/multiformats/go-multicodec/pull/71)) + +
### Contributors - +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| Antonio Navarro Perez | 11 | +780/-987 | 31 | +| Marcin Rataj | 14 | +791/-543 | 26 | +| web3-bot | 7 | +393/-427 | 71 | +| galargh | 20 | +309/-277 | 21 | +| Gus Eggert | 5 | +358/-222 | 58 | +| Henrique Dias | 3 | +409/-30 | 13 | +| Dustin Long | 1 | +314/-0 | 2 | +| Marco Munizaga | 2 | +211/-46 | 11 | +| Rod Vagg | 4 | +188/-62 | 13 | +| Jorropo | 2 | +4/-219 | 5 | +| Steve Loeppky | 1 | +115/-72 | 4 | +| Andreas Källberg | 1 | +145/-5 | 5 | +| Lucas Molas | 3 | +76/-53 | 9 | +| snyh | 2 | +36/-18 | 2 | +| Piotr Galar | 2 | +31/-4 | 2 | +| Ondrej Kokes | 1 | +25/-4 | 2 | +| Marten Seemann | 6 | +14/-14 | 14 | +| Yann Autissier | 1 | +14/-4 | 1 | +| maxos | 1 | +8/-1 | 2 | +| reidlw | 1 | +1/-4 | 1 | +| Russell Dempsey | 2 | +4/-1 | 2 | +| Ian Davis | 1 | +4/-0 | 2 | +| Daniel Norman | 1 | +3/-1 | 1 | +| Will Scott | 1 | +1/-1 | 1 | +| Nikhilesh Susarla | 1 | +2/-0 | 2 | +| Jamie Wilkinson | 1 | +1/-1 | 1 | +| Will | 1 | +0/-1 | 1 |