Revert "Doc improvements for rcmgr"
This reverts commit b1a89c93e4e0ff92f855477a5f4d882b96cd2188.
Steve Loeppky committed
Nov 16, 2022 at 08:32 UTC
9eeca82269c4aa4b07f8f065b0835f712144b715
4 files changed
+64
-112
core/node/libp2p/rcmgr.go
+4
-8
@@ -52,22 +52,18 @@ func ResourceManager(cfg config.SwarmConfig) interface{} {
52
return nil, opts, fmt.Errorf("opening IPFS_PATH: %w", err)
53
}
54
55
- limitConfig, err := createDefaultLimitConfig(cfg)
55
+ limits, err := createDefaultLimitConfig(cfg)
56
if err != nil {
57
return nil, opts, err
58
}
59
60
- // The logic for defaults and overriding with specified SwarmConfig.ResourceMgr.Limits
61
- // is documented in docs/config.md.
62
- // Any changes here should be reflected there.
60
if cfg.ResourceMgr.Limits != nil {
61
l := *cfg.ResourceMgr.Limits
65
- // This effectively overrides the computed default LimitConfig with any vlues from cfg.ResourceMgr.Limits
66
- l.Apply(limitConfig)
67
- limitConfig = l
62
+ l.Apply(limits)
63
+ limits = l
64
}
65
70
- limiter := rcmgr.NewFixedLimiter(limitConfig)
66
+ limiter := rcmgr.NewFixedLimiter(limits)
67
68
str, err := rcmgrObs.NewStatsTraceReporter()
69
if err != nil {
core/node/libp2p/rcmgr_defaults.go
+46
-2
@@ -44,8 +44,51 @@ var noLimitIncrease = rcmgr.BaseLimitIncrease{
44
// This file defines implicit limit defaults used when Swarm.ResourceMgr.Enabled
45
46
// createDefaultLimitConfig creates LimitConfig to pass to libp2p's resource manager.
47
-// The defaults follow the documentation in docs/config.md.
48
-// Any changes in the logic here should be reflected there.
47
+// libp2p's resource manager provides tremendous flexibility but also adds a lot of complexity.
48
+// The intent of the default config here is to provide good defaults,
49
+// and where the defaults aren't good enough,
50
+// to expose a good set of higher-level "knobs" to users to satisfy most use cases
51
+// without requiring users to wade into all the intricacies of libp2p's resource manager.
52
+//
53
+// The inputs one can specify in SwarmConfig are:
54
+// - cfg.ResourceMgr.MaxMemory: This is the max amount of memory in bytes to allow libp2p to use.
55
+// libp2p's resource manager will prevent additional resource creation while this limit is hit.
56
+// If this value isn't specified, 1/8th of the total system memory is used.
57
+// - cfg.ResourceMgr.MaxFileDescriptors: This is the maximum number of file descriptors to allow libp2p to use.
58
+// libp2p's resource manager will prevent additional file descriptor consumption while this limit is hit.
59
+// If this value isn't specified, the maximum between 1/2 of system FD limit and 4096 is used.
60
+// - Swarm.ConnMgr.HighWater: If a connection manager is specified, libp2p's resource manager
61
+// will allow 2x more connections than the HighWater mark
62
+// so the connection manager has "space and time" to close "least useful" connections.
63
+//
64
+// With these inputs defined, limits are created at the system, transient, and peer scopes.
65
+// Other scopes are ignored (by being set to infinity).
66
+// The reason these scopes are chosen is because:
67
+// - system - This gives us the coarse-grained control we want so we can reason about the system as a whole.
68
+// It is the backstop, and allows us to reason about resource consumption more easily
69
+// since don't have think about the interaction of many other scopes.
70
+// - transient - Limiting connections that are in process of being established provides backpressure so not too much work queues up.
71
+// - peer - The peer scope doesn't protect us against intentional DoS attacks.
72
+// It's just as easy for an attacker to send 100 requests/second with 1 peerId vs. 10 requests/second with 10 peers.
73
+// We are reliant on the system scope for protection here in the malicious case.
74
+// The reason for having a peer scope is to protect against unintentional DoS attacks
75
+// (e.g., bug in a peer which is causing it to "misbehave").
76
+// In the unintional case, we want to make sure a "misbehaving" node doesn't consume more resources than necessary.
77
+//
78
+// Within these scopes, limits are just set on memory, FD, and inbound connections/streams.
79
+// Limits are set based on the inputs above.
80
+// We trust this node to behave properly and thus ignore outbound connection/stream limits.
81
+// We apply any limits that libp2p has for its protocols/services
82
+// since we assume libp2p knows best here.
83
+//
84
+// This leaves 3 levels of resource management protection:
85
+// 1. The user who does nothing and uses defaults - In this case they get some sane defaults
86
+// based on the amount of memory and file descriptors their system has.
87
+// This should protect the node from many attacks.
88
+// 2. Slightly more advanced user - They can tweak the above by passing in config on
89
+// maxMemory, maxFD, or maxConns with Swarm.HighWater.ConnMgr.
90
+// 3. Power user - They specify all the limits they want set via Swarm.ResourceMgr.Limits
91
+// and we don't do any defaults/overrides. We pass that config blindly into libp2p resource manager.
92
func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.LimitConfig, error) {
93
maxMemoryDefaultString := humanize.Bytes(uint64(memory.TotalMemory()) / 8)
94
maxMemoryString := cfg.ResourceMgr.MaxMemory.WithDefault(maxMemoryDefaultString)
@@ -62,6 +105,7 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.LimitConfig, error)
105
FD: int(numFD),
106
107
// By default, we just limit connections on the inbound side.
108
+ // Note that the limit gets adjusted below if "cfg.ConnMgr.HighWater" is set.
109
Conns: bigEnough,
110
ConnsInbound: rcmgr.DefaultLimits.SystemBaseLimit.ConnsInbound, // same as libp2p default
111
ConnsOutbound: bigEnough,
docs/changelogs/v0.17.md
-22
@@ -20,28 +20,6 @@ Below is an outline of all that is in this release, so you get a sense of all th
20
21
<!-- TODO -->
22
23
-#### libp2p resource management enabled by default
24
-
25
-To help protect nodes from DoS (resource exhaustion) and eclipse attacks,
26
-go-libp2p released a [Network Resource Manager](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manage) with a host of improvements throughout 2022.
27
-
28
-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),
29
-but it was disabled by default.
30
-
31
-The resource manager is now enabled by default to protect nodes.
32
-The defaults balance providing protection from various attacks while still enabling normal usecases to work as expected.
33
-
34
-If you want to adjust the defaults, then you can:
35
-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)
36
-and Swarm.ResourceMgr.MaxFileDescriptors](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgrmaxfiledescriptors) and/or
37
-2. override any specific resource scopes/limits with [Swarm.ResourceMgr.Limits](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgrlimits)
38
-
39
-See [Swarm.ResourceMgr](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgr) for
40
-1. what limits are set by default,
41
-2. example override configuration,
42
-3. how to access prometheus metrics and view grafana dashboards of resource usage, and
43
-4. how to set explicit "allow lists" to protect against eclipse attacks.
44
-
23
#### Implicit connection manager limits
24
25
Starting with this release, `ipfs init` will no longer store the default
docs/config.md
+14
-80
@@ -1808,76 +1808,30 @@ Type: `optionalDuration`
1808
1809
### `Swarm.ResourceMgr`
1810
1811
-The [libp2p Netowrk Resource Manager](https://github.com/libp2p/go-libp2p-resource-manager#readme) allows setting limits per [Resource Scope](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#resource-scopes),
1811
+The [libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p-resource-manager#readme) allows setting limits per a scope,
1812
and tracking recource usage over time.
1813
1814
-** Levels of Configuration **
1815
-libp2p's resource manager provides tremendous flexibility but also adds a lot of complexity.
1816
-There are these levels of limit configuration for resource management protection:
1817
-1. "The user who does nothing" - In this case they get some sane defaults discussed below
1818
- based on the amount of memory and file descriptors their system has.
1819
- This should protect the node from many attacks.
1820
-2. "Slightly more advanced user" - They can tweak the default limits discussed below.
1821
- Where the defaults aren't good enough, a good set of higher-level "knobs" are exposed to satisfy most use cases
1822
- without requiring users to wade into all the intricacies of libp2p's resource manager.
1823
- The "knobs"/inputs are `Swarm.ResourceMgr.MaxMemory` and `Swarm.ResourceMgr.MaxFileDescriptors` as described below.
1824
-3. "Power user" - They specify all the default limits from below they want override via `Swarm.ResourceMgr.Limits`;
1825
-
1826
-** Default Limits **
1827
-With these inputs defined, [resource manager limits](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#limits) are created at the
1828
-[system](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#the-system-scope),
1829
-[transient](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#the-transient-scope),
1830
-and [peer](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#peer-scopes) scopes.
1831
-Other scopes are ignored (by being set to "~infinity".
1832
-
1833
-The reason these scopes are chosen is because:
1834
-- system - This gives us the coarse-grained control we want so we can reason about the system as a whole.
1835
- It is the backstop, and allows us to reason about resource consumption more easily
1836
- since don't have think about the interaction of many other scopes.
1837
-- transient - Limiting connections that are in process of being established provides backpressure so not too much work queues up.
1838
-- peer - The peer scope doesn't protect us against intentional DoS attacks.
1839
- It's just as easy for an attacker to send 100 requests/second with 1 peerId vs. 10 requests/second with 10 peers.
1840
- We are reliant on the system scope for protection here in the malicious case.
1841
- The reason for having a peer scope is to protect against unintentional DoS attacks
1842
- (e.g., bug in a peer which is causing it to "misbehave").
1843
- In the unintional case, we want to make sure a "misbehaving" node doesn't consume more resources than necessary.
1844
-
1845
-Within these scopes, limits are just set on
1846
-[memory](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#memory),
1847
-[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),
1848
-and [*inbound* streams](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#streams).
1849
-Limits are set based on the inputs above.
1850
-We trust this node to behave properly and thus don't limit *outbound* connection/stream limits.
1851
-We apply any limits that libp2p has for its protocols/services
1852
-since we assume libp2p knows best here.
1853
-
1854
-** libp2p resource monitoring **
1855
-For [monitoring libp2p resource usage](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#monitoring),
1856
-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`).
1857
-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.
1858
-
1814
#### `Swarm.ResourceMgr.Enabled`
1815
1861
-Enables the libp2p Resource Manager using limits based on the defaults and/or other configuration as discussed above.
1816
+Enables the libp2p Network Resource Manager and auguments the default limits
1817
+using user-defined ones in `Swarm.ResourceMgr.Limits` (if present).
1818
+
1819
+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`)
1820
1821
Default: `true`
1822
+
1823
Type: `flag`
1824
1825
#### `Swarm.ResourceMgr.MaxMemory`
1826
1868
-This is the max amount of memory to allow libp2p to use.
1869
-libp2p's resource manager will prevent additional resource creation while this limit is reached.
1870
-This value is also used to scale the limit on various resources at various scopes
1871
-when the default limits (discuseed above) are used.
1872
-For example, increasing this value will increase the default limit for incoming connections.
1827
+The maximum amount of memory that the libp2p resource manager will allow.
1828
1829
Default: `[TOTAL_SYSTEM_MEMORY]/8`
1830
Type: `optionalBytes`
1831
1832
#### `Swarm.ResourceMgr.MaxFileDescriptors`
1833
1879
-This is the maximum number of file descriptors to allow libp2p to use.
1880
-libp2p's resource manager will prevent additional file descriptor consumption while this limit is reached.
1834
+Define the maximum number of file descriptors that libp2p can use.
1835
1836
This param is ignored on Windows.
1837
@@ -1888,26 +1842,21 @@ Type: `optionalInteger`
1842
1843
Map of resource limits [per scope](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#resource-scopes).
1844
1891
-The map supports fields from the [`LimitConfig` struct](https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/limit_defaults.go#L111).
1845
+The map supports fields from [`ScalingLimitConfig`](https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/limit_defaults.go#L21-L59)
1846
+struct from [go-libp2p-resource-manager](https://github.com/libp2p/go-libp2p/tree/master/p2p/host/resource-manager#readme).
1847
1893
-[`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 <key,value>s are optional.
1894
-
1895
-The `Swarm.ResourceMgr.Limits` override the default limits described above.
1896
-Any override `BaseLimits` or limit <key,value>s from `Swarm.ResourceMgr.Limits`
1897
-that aren't specified will use the default limits.
1898
-
1899
-Example #1: setting limits for a specific scope
1848
```json
1849
{
1850
"Swarm": {
1851
"ResourceMgr": {
1852
+ "Enabled": true,
1853
"Limits": {
1854
"System": {
1906
- "Memory": 1073741824,
1907
- "FD": 512,
1855
"Conns": 1024,
1856
"ConnsInbound": 256,
1857
"ConnsOutbound": 1024,
1858
+ "FD": 512,
1859
+ "Memory": 1073741824,
1860
"Streams": 16384,
1861
"StreamsInbound": 4096,
1862
"StreamsOutbound": 16384
@@ -1918,28 +1867,13 @@ Example #1: setting limits for a specific scope
1867
}
1868
```
1869
1921
-Example #2: setting a specific <key,value> limit
1922
-```json
1923
-{
1924
- "Swarm": {
1925
- "ResourceMgr": {
1926
- "Limits": {
1927
- "Transient": {
1928
- "ConnsOutbound": 256,
1929
- }
1930
- }
1931
- }
1932
- }
1933
-}
1934
-```
1935
-
1870
Current resource usage and a list of services, protocols, and peers can be
1871
obtained via `ipfs swarm stats --help`
1872
1873
It is also possible to adjust some runtime limits via `ipfs swarm limit --help`.
1874
Changes made via `ipfs swarm limit` are persisted in `Swarm.ResourceMgr.Limits`.
1875
1942
-Default: `{}` (use the safe implicit defaults described above)
1876
+Default: `{}` (use the safe implicit defaults)
1877
1878
Type: `object[string->object]`
1879