1
package libp2p
2
3
import (
4
- "encoding/json"
5
- "fmt"
6
- "math/bits"
7
- "os"
8
- "strings"
4
+ "math"
5
10
- "github.com/ipfs/kubo/config"
6
+ "github.com/dustin/go-humanize"
7
"github.com/libp2p/go-libp2p"
8
rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
9
+ "github.com/pbnjay/memory"
10
14
- "github.com/wI2L/jsondiff"
11
+ "github.com/ipfs/kubo/config"
12
+ "github.com/ipfs/kubo/core/node/libp2p/fd"
13
)
14
17
-// This file defines implicit limit defaults used when Swarm.ResourceMgr.Enabled
18
-
19
-// adjustedDefaultLimits allows for tweaking defaults based on external factors,
20
-// such as values in Swarm.ConnMgr.HiWater config.
21
-func adjustedDefaultLimits(cfg config.SwarmConfig) rcmgr.LimitConfig {
22
- // Run checks to avoid introducing regressions
23
- if os.Getenv("IPFS_CHECK_RCMGR_DEFAULTS") != "" {
24
- checkImplicitDefaults()
25
- }
26
- defaultLimits := rcmgr.DefaultLimits
27
- libp2p.SetDefaultServiceLimits(&defaultLimits)
28
-
29
- // Adjust limits
30
- // (based on https://github.com/filecoin-project/lotus/pull/8318/files)
31
- // - if Swarm.ConnMgr.HighWater is too high, adjust Conn/FD/Stream limits
32
-
33
- // Outbound conns and FDs are set very high to allow for the accelerated DHT client to (re)load its routing table.
34
- // Currently it doesn't gracefully handle RM throttling--once it does we can lower these.
35
- // High outbound conn limits are considered less of a DoS risk than high inbound conn limits.
36
- // Also note that, due to the behavior of the accelerated DHT client, we don't need many streams, just conns.
37
- if minOutbound := 65536; defaultLimits.SystemBaseLimit.ConnsOutbound < minOutbound {
38
- defaultLimits.SystemBaseLimit.ConnsOutbound = minOutbound
39
- }
40
- if minFD := 4096; defaultLimits.SystemBaseLimit.FD < minFD {
41
- defaultLimits.SystemBaseLimit.FD = minFD
42
- }
43
- defaultLimitConfig := defaultLimits.AutoScale()
44
-
45
- // Do we need to adjust due to Swarm.ConnMgr.HighWater?
46
- if cfg.ConnMgr.Type == "basic" {
47
- maxconns := cfg.ConnMgr.HighWater
48
- if 2*maxconns > defaultLimitConfig.System.ConnsInbound {
49
- // adjust conns to 2x to allow for two conns per peer (TCP+QUIC)
50
- defaultLimitConfig.System.ConnsInbound = logScale(2 * maxconns)
51
- defaultLimitConfig.System.ConnsOutbound = logScale(2 * maxconns)
52
- defaultLimitConfig.System.Conns = logScale(4 * maxconns)
53
-
54
- defaultLimitConfig.System.StreamsInbound = logScale(16 * maxconns)
55
- defaultLimitConfig.System.StreamsOutbound = logScale(64 * maxconns)
56
- defaultLimitConfig.System.Streams = logScale(64 * maxconns)
57
-
58
- if 2*maxconns > defaultLimitConfig.System.FD {
59
- defaultLimitConfig.System.FD = logScale(2 * maxconns)
60
- }
61
-
62
- defaultLimitConfig.ServiceDefault.StreamsInbound = logScale(8 * maxconns)
63
- defaultLimitConfig.ServiceDefault.StreamsOutbound = logScale(32 * maxconns)
64
- defaultLimitConfig.ServiceDefault.Streams = logScale(32 * maxconns)
65
-
66
- defaultLimitConfig.ProtocolDefault.StreamsInbound = logScale(8 * maxconns)
67
- defaultLimitConfig.ProtocolDefault.StreamsOutbound = logScale(32 * maxconns)
68
- defaultLimitConfig.ProtocolDefault.Streams = logScale(32 * maxconns)
69
-
70
- log.Info("adjusted default resource manager limits")
71
- }
72
-
73
- }
74
-
75
- return defaultLimitConfig
15
+// We are doing some magic when parsing config files (we are using a map[string]interface{} to compare config files).
16
+// When you don't have a type the JSON Parse function cast numbers to float64 by default,
17
+// losing precision when writing the final number. So if we use math.MaxInt as our infinite number,
18
+// after writing the config file we will have 9223372036854776000 instead of 9223372036854775807,
19
+// making the parsing process fail.
20
+const bigEnough = math.MaxInt / 2
21
+
22
+var infiniteBaseLimit = rcmgr.BaseLimit{
23
+ Streams: bigEnough,
24
+ StreamsInbound: bigEnough,
25
+ StreamsOutbound: bigEnough,
26
+ Conns: bigEnough,
27
+ ConnsInbound: bigEnough,
28
+ ConnsOutbound: bigEnough,
29
+ FD: bigEnough,
30
+ Memory: bigEnough,
31
}
32
78
-func logScale(val int) int {
79
- bitlen := bits.Len(uint(val))
80
- return 1 << bitlen
33
+var noLimitIncrease = rcmgr.BaseLimitIncrease{
34
+ ConnsInbound: 0,
35
+ ConnsOutbound: 0,
36
+ Conns: 0,
37
+ StreamsInbound: 0,
38
+ StreamsOutbound: 0,
39
+ Streams: 0,
40
+ Memory: 0,
41
+ FDFraction: 0,
42
}
43
83
-// checkImplicitDefaults compares libp2p defaults agains expected ones
84
-// and panics when they don't match. This ensures we are not surprised
85
-// by silent default limit changes when we update go-libp2p dependencies.
86
-func checkImplicitDefaults() {
87
- ok := true
44
+// This file defines implicit limit defaults used when Swarm.ResourceMgr.Enabled
45
89
- // Check 1: did go-libp2p-resource-manager's DefaultLimits change?
90
- defaults, err := json.Marshal(rcmgr.DefaultLimits)
46
+// createDefaultLimitConfig creates LimitConfig to pass to libp2p's resource manager.
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)
95
+ maxMemory, err := humanize.ParseBytes(maxMemoryString)
96
if err != nil {
92
- log.Fatal(err)
93
- }
94
- changes, err := jsonDiff([]byte(expectedDefaultLimits), defaults)
95
- if err != nil {
96
- log.Fatal(err)
97
- }
98
- if len(changes) > 0 {
99
- ok = false
100
- log.Errorf("===> OOF! go-libp2p-resource-manager changed DefaultLimits\n"+
101
- "=> changes ('test' represents the old value):\n%s\n"+
102
- "=> go-libp2p-resource-manager DefaultLimits update needs a review:\n"+
103
- "Please inspect if changes impact go-ipfs users, and update expectedDefaultLimits in rcmgr_defaults.go to remove this message",
104
- strings.Join(changes, "\n"),
105
- )
97
+ return rcmgr.LimitConfig{}, err
98
}
99
108
- // Check 2: did go-libp2p's SetDefaultServiceLimits change?
109
- // We compare the baseline (min specs), and check if we went down in any limits.
110
- l := rcmgr.DefaultLimits
111
- libp2p.SetDefaultServiceLimits(&l)
112
- limits := l.AutoScale()
113
- testLimiter := rcmgr.NewFixedLimiter(limits)
114
-
115
- serviceDefaults, err := json.Marshal(testLimiter)
116
- if err != nil {
117
- log.Fatal(err)
118
- }
119
- changes, err = jsonDiff([]byte(expectedDefaultServiceLimits), serviceDefaults)
120
- if err != nil {
121
- log.Fatal(err)
100
+ numFD := cfg.ResourceMgr.MaxFileDescriptors.WithDefault(int64(fd.GetNumFDs()) / 2)
101
+
102
+ scalingLimitConfig := rcmgr.ScalingLimitConfig{
103
+ SystemBaseLimit: rcmgr.BaseLimit{
104
+ Memory: int64(maxMemory),
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,
112
+
113
+ // We limit streams since they not only take up memory and CPU.
114
+ // The Memory limit protects us on the memory side,
115
+ // but a StreamsInbound limit helps protect against unbound CPU consumption from stream processing.
116
+ Streams: bigEnough,
117
+ StreamsInbound: rcmgr.DefaultLimits.SystemBaseLimit.StreamsInbound,
118
+ StreamsOutbound: bigEnough,
119
+ },
120
+ // Most limits don't see an increase because they're already infinite/bigEnough or at their max value.
121
+ // The values that should scale based on the amount of memory allocated to libp2p need to increase accordingly.
122
+ SystemLimitIncrease: rcmgr.BaseLimitIncrease{
123
+ Memory: rcmgr.DefaultLimits.SystemLimitIncrease.Memory,
124
+ FDFraction: rcmgr.DefaultLimits.SystemLimitIncrease.FDFraction,
125
+
126
+ Conns: 0,
127
+ ConnsInbound: rcmgr.DefaultLimits.SystemLimitIncrease.ConnsInbound,
128
+ ConnsOutbound: 0,
129
+
130
+ Streams: 0,
131
+ StreamsInbound: rcmgr.DefaultLimits.SystemLimitIncrease.StreamsInbound,
132
+ StreamsOutbound: 0,
133
+ },
134
+
135
+ // Just go with what libp2p does
136
+ TransientBaseLimit: rcmgr.DefaultLimits.TransientBaseLimit,
137
+ TransientLimitIncrease: rcmgr.DefaultLimits.TransientLimitIncrease,
138
+
139
+ // Lets get out of the way of the allow list functionality.
140
+ // If someone specified "Swarm.ResourceMgr.Allowlist" we should let it go through.
141
+ AllowlistedSystemBaseLimit: infiniteBaseLimit,
142
+ AllowlistedSystemLimitIncrease: noLimitIncrease,
143
+
144
+ AllowlistedTransientBaseLimit: infiniteBaseLimit,
145
+ AllowlistedTransientLimitIncrease: noLimitIncrease,
146
+
147
+ // Keep it simple by not having Service, ServicePeer, Protocol, ProtocolPeer, Conn, or Stream limits.
148
+ ServiceBaseLimit: infiniteBaseLimit,
149
+ ServiceLimitIncrease: noLimitIncrease,
150
+
151
+ ServicePeerBaseLimit: infiniteBaseLimit,
152
+ ServicePeerLimitIncrease: noLimitIncrease,
153
+
154
+ ProtocolBaseLimit: infiniteBaseLimit,
155
+ ProtocolLimitIncrease: noLimitIncrease,
156
+
157
+ ProtocolPeerBaseLimit: infiniteBaseLimit,
158
+ ProtocolPeerLimitIncrease: noLimitIncrease,
159
+
160
+ ConnBaseLimit: infiniteBaseLimit,
161
+ ConnLimitIncrease: noLimitIncrease,
162
+
163
+ StreamBaseLimit: infiniteBaseLimit,
164
+ StreamLimitIncrease: noLimitIncrease,
165
+
166
+ // Limit the resources consumed by a peer.
167
+ // This doesn't protect us against intentional DoS attacks since an attacker can easily spin up multiple peers.
168
+ // We specify this limit against unintentional DoS attacks (e.g., a peer has a bug and is sending too much traffic intentionally).
169
+ // In that case we want to keep that peer's resource consumption contained.
170
+ // To keep this simple, we only constrain inbound connections and streams.
171
+ PeerBaseLimit: rcmgr.BaseLimit{
172
+ Memory: bigEnough,
173
+ FD: bigEnough,
174
+ Conns: bigEnough,
175
+ ConnsInbound: rcmgr.DefaultLimits.PeerBaseLimit.ConnsInbound,
176
+ ConnsOutbound: bigEnough,
177
+ Streams: bigEnough,
178
+ StreamsInbound: rcmgr.DefaultLimits.PeerBaseLimit.StreamsInbound,
179
+ StreamsOutbound: bigEnough,
180
+ },
181
+ // Most limits don't see an increase because they're already infinite/bigEnough.
182
+ // The values that should scale based on the amount of memory allocated to libp2p need to increase accordingly.
183
+ PeerLimitIncrease: rcmgr.BaseLimitIncrease{
184
+ Memory: 0,
185
+ FDFraction: 0,
186
+ Conns: 0,
187
+ ConnsInbound: rcmgr.DefaultLimits.PeerLimitIncrease.ConnsInbound,
188
+ ConnsOutbound: 0,
189
+ Streams: 0,
190
+ StreamsInbound: rcmgr.DefaultLimits.PeerLimitIncrease.StreamsInbound,
191
+ StreamsOutbound: 0,
192
+ },
193
}
123
- if len(changes) > 0 {
124
- oldState := map[string]int{}
125
- type Op struct {
126
- Op string
127
- Path string
128
- Value int
129
- }
130
- for _, changeStr := range changes {
131
- change := Op{}
132
- err := json.Unmarshal([]byte(changeStr), &change)
133
- if err != nil {
134
- continue
135
- }
136
- if change.Op == "test" {
137
- oldState[change.Path] = change.Value
138
- }
139
- }
194
141
- for _, changeStr := range changes {
142
- change := Op{}
143
- err := json.Unmarshal([]byte(changeStr), &change)
144
- if err != nil {
145
- continue
146
- }
147
- if change.Op == "replace" {
148
- oldVal, okFound := oldState[change.Path]
149
- if okFound && oldVal > change.Value {
150
- ok = false
151
- fmt.Printf("reduced value for %s. Old: %v; new: %v\n", change.Path, oldVal, change.Value)
152
- }
153
- }
154
- }
195
+ // Whatever limits libp2p has specifically tuned for its protocols/services we'll apply.
196
+ libp2p.SetDefaultServiceLimits(&scalingLimitConfig)
197
156
- if !ok {
157
- log.Errorf("===> OOF! go-libp2p changed DefaultServiceLimits\n" +
158
- "=> See the aboce reduced values for info.\n" +
159
- "=> go-libp2p SetDefaultServiceLimits update needs a review:\n" +
160
- "Please inspect if changes impact go-ipfs users, and update expectedDefaultServiceLimits in rcmgr_defaults.go to remove this message",
161
- )
162
- }
163
- }
164
- if !ok {
165
- log.Fatal("daemon will refuse to run with the resource manager until this is resolved")
166
- }
167
-}
198
+ defaultLimitConfig := scalingLimitConfig.Scale(int64(maxMemory), int(numFD))
199
169
-// jsonDiff compares two strings and returns diff in JSON Patch format
170
-func jsonDiff(old []byte, updated []byte) ([]string, error) {
171
- // generate 'invertible' patch which includes old values as "test" op
172
- patch, err := jsondiff.CompareJSONOpts(old, updated, jsondiff.Invertible())
173
- changes := make([]string, len(patch))
174
- if err != nil {
175
- return changes, err
176
- }
177
- for i, op := range patch {
178
- changes[i] = fmt.Sprintf(" %s", op)
200
+ // If a high water mark is set:
201
+ if cfg.ConnMgr.Type == "basic" {
202
+ // set the connection limit higher than high water mark so that the ConnMgr has "space and time" to close "least useful" connections.
203
+ defaultLimitConfig.System.Conns = 2 * cfg.ConnMgr.HighWater
204
+ log.Info("adjusted default resource manager System.Conns limits to match ConnMgr.HighWater value of %s", cfg.ConnMgr.HighWater)
205
}
180
- return changes, nil
181
-}
206
183
-// https://github.com/libp2p/go-libp2p/blob/v0.22.0/p2p/host/resource-manager/limit_defaults.go#L343
184
-const expectedDefaultLimits = `{
185
- "SystemBaseLimit": {
186
- "Streams": 2048,
187
- "StreamsInbound": 1024,
188
- "StreamsOutbound": 2048,
189
- "Conns": 128,
190
- "ConnsInbound": 64,
191
- "ConnsOutbound": 128,
192
- "FD": 256,
193
- "Memory": 134217728
194
- },
195
- "SystemLimitIncrease": {
196
- "Streams": 2048,
197
- "StreamsInbound": 1024,
198
- "StreamsOutbound": 2048,
199
- "Conns": 128,
200
- "ConnsInbound": 64,
201
- "ConnsOutbound": 128,
202
- "Memory": 1073741824,
203
- "FDFraction": 1
204
- },
205
- "TransientBaseLimit": {
206
- "Streams": 256,
207
- "StreamsInbound": 128,
208
- "StreamsOutbound": 256,
209
- "Conns": 64,
210
- "ConnsInbound": 32,
211
- "ConnsOutbound": 64,
212
- "FD": 64,
213
- "Memory": 33554432
214
- },
215
- "TransientLimitIncrease": {
216
- "Streams": 256,
217
- "StreamsInbound": 128,
218
- "StreamsOutbound": 256,
219
- "Conns": 32,
220
- "ConnsInbound": 16,
221
- "ConnsOutbound": 32,
222
- "Memory": 134217728,
223
- "FDFraction": 0.25
224
- },
225
- "AllowlistedSystemBaseLimit": {
226
- "Streams": 2048,
227
- "StreamsInbound": 1024,
228
- "StreamsOutbound": 2048,
229
- "Conns": 128,
230
- "ConnsInbound": 64,
231
- "ConnsOutbound": 128,
232
- "FD": 256,
233
- "Memory": 134217728
234
- },
235
- "AllowlistedSystemLimitIncrease": {
236
- "Streams": 2048,
237
- "StreamsInbound": 1024,
238
- "StreamsOutbound": 2048,
239
- "Conns": 128,
240
- "ConnsInbound": 64,
241
- "ConnsOutbound": 128,
242
- "Memory": 1073741824,
243
- "FDFraction": 1
244
- },
245
- "AllowlistedTransientBaseLimit": {
246
- "Streams": 256,
247
- "StreamsInbound": 128,
248
- "StreamsOutbound": 256,
249
- "Conns": 64,
250
- "ConnsInbound": 32,
251
- "ConnsOutbound": 64,
252
- "FD": 64,
253
- "Memory": 33554432
254
- },
255
- "AllowlistedTransientLimitIncrease": {
256
- "Streams": 256,
257
- "StreamsInbound": 128,
258
- "StreamsOutbound": 256,
259
- "Conns": 32,
260
- "ConnsInbound": 16,
261
- "ConnsOutbound": 32,
262
- "Memory": 134217728,
263
- "FDFraction": 0.25
264
- },
265
- "ServiceBaseLimit": {
266
- "Streams": 4096,
267
- "StreamsInbound": 1024,
268
- "StreamsOutbound": 4096,
269
- "Conns": 0,
270
- "ConnsInbound": 0,
271
- "ConnsOutbound": 0,
272
- "FD": 0,
273
- "Memory": 67108864
274
- },
275
- "ServiceLimitIncrease": {
276
- "Streams": 2048,
277
- "StreamsInbound": 512,
278
- "StreamsOutbound": 2048,
279
- "Conns": 0,
280
- "ConnsInbound": 0,
281
- "ConnsOutbound": 0,
282
- "Memory": 134217728,
283
- "FDFraction": 0
284
- },
285
- "ServiceLimits": null,
286
- "ServicePeerBaseLimit": {
287
- "Streams": 256,
288
- "StreamsInbound": 128,
289
- "StreamsOutbound": 256,
290
- "Conns": 0,
291
- "ConnsInbound": 0,
292
- "ConnsOutbound": 0,
293
- "FD": 0,
294
- "Memory": 16777216
295
- },
296
- "ServicePeerLimitIncrease": {
297
- "Streams": 8,
298
- "StreamsInbound": 4,
299
- "StreamsOutbound": 8,
300
- "Conns": 0,
301
- "ConnsInbound": 0,
302
- "ConnsOutbound": 0,
303
- "Memory": 4194304,
304
- "FDFraction": 0
305
- },
306
- "ServicePeerLimits": null,
307
- "ProtocolBaseLimit": {
308
- "Streams": 2048,
309
- "StreamsInbound": 512,
310
- "StreamsOutbound": 2048,
311
- "Conns": 0,
312
- "ConnsInbound": 0,
313
- "ConnsOutbound": 0,
314
- "FD": 0,
315
- "Memory": 67108864
316
- },
317
- "ProtocolLimitIncrease": {
318
- "Streams": 512,
319
- "StreamsInbound": 256,
320
- "StreamsOutbound": 512,
321
- "Conns": 0,
322
- "ConnsInbound": 0,
323
- "ConnsOutbound": 0,
324
- "Memory": 171966464,
325
- "FDFraction": 0
326
- },
327
- "ProtocolLimits": null,
328
- "ProtocolPeerBaseLimit": {
329
- "Streams": 256,
330
- "StreamsInbound": 64,
331
- "StreamsOutbound": 128,
332
- "Conns": 0,
333
- "ConnsInbound": 0,
334
- "ConnsOutbound": 0,
335
- "FD": 0,
336
- "Memory": 16777216
337
- },
338
- "ProtocolPeerLimitIncrease": {
339
- "Streams": 16,
340
- "StreamsInbound": 4,
341
- "StreamsOutbound": 8,
342
- "Conns": 0,
343
- "ConnsInbound": 0,
344
- "ConnsOutbound": 0,
345
- "Memory": 4,
346
- "FDFraction": 0
347
- },
348
- "ProtocolPeerLimits": null,
349
- "PeerBaseLimit": {
350
- "Streams": 512,
351
- "StreamsInbound": 256,
352
- "StreamsOutbound": 512,
353
- "Conns": 8,
354
- "ConnsInbound": 4,
355
- "ConnsOutbound": 8,
356
- "FD": 4,
357
- "Memory": 67108864
358
- },
359
- "PeerLimitIncrease": {
360
- "Streams": 256,
361
- "StreamsInbound": 128,
362
- "StreamsOutbound": 256,
363
- "Conns": 0,
364
- "ConnsInbound": 0,
365
- "ConnsOutbound": 0,
366
- "Memory": 134217728,
367
- "FDFraction": 0.015625
368
- },
369
- "PeerLimits": null,
370
- "ConnBaseLimit": {
371
- "Streams": 0,
372
- "StreamsInbound": 0,
373
- "StreamsOutbound": 0,
374
- "Conns": 1,
375
- "ConnsInbound": 1,
376
- "ConnsOutbound": 1,
377
- "FD": 1,
378
- "Memory": 33554432
379
- },
380
- "ConnLimitIncrease": {
381
- "Streams": 0,
382
- "StreamsInbound": 0,
383
- "StreamsOutbound": 0,
384
- "Conns": 0,
385
- "ConnsInbound": 0,
386
- "ConnsOutbound": 0,
387
- "Memory": 0,
388
- "FDFraction": 0
389
- },
390
- "StreamBaseLimit": {
391
- "Streams": 1,
392
- "StreamsInbound": 1,
393
- "StreamsOutbound": 1,
394
- "Conns": 0,
395
- "ConnsInbound": 0,
396
- "ConnsOutbound": 0,
397
- "FD": 0,
398
- "Memory": 16777216
399
- },
400
- "StreamLimitIncrease": {
401
- "Streams": 0,
402
- "StreamsInbound": 0,
403
- "StreamsOutbound": 0,
404
- "Conns": 0,
405
- "ConnsInbound": 0,
406
- "ConnsOutbound": 0,
407
- "Memory": 0,
408
- "FDFraction": 0
409
- }
410
-}`
411
-
412
-// Generated from the default limits and scaling to 0 (base limit).
413
-const expectedDefaultServiceLimits = `{
414
- "System": {
415
- "Streams": 2048,
416
- "StreamsInbound": 1024,
417
- "StreamsOutbound": 2048,
418
- "Conns": 128,
419
- "ConnsInbound": 64,
420
- "ConnsOutbound": 128,
421
- "FD": 256,
422
- "Memory": 134217728
423
- },
424
- "Transient": {
425
- "Streams": 256,
426
- "StreamsInbound": 128,
427
- "StreamsOutbound": 256,
428
- "Conns": 64,
429
- "ConnsInbound": 32,
430
- "ConnsOutbound": 64,
431
- "FD": 64,
432
- "Memory": 33554432
433
- },
434
- "AllowlistedSystem": {
435
- "Streams": 2048,
436
- "StreamsInbound": 1024,
437
- "StreamsOutbound": 2048,
438
- "Conns": 128,
439
- "ConnsInbound": 64,
440
- "ConnsOutbound": 128,
441
- "FD": 256,
442
- "Memory": 134217728
443
- },
444
- "AllowlistedTransient": {
445
- "Streams": 256,
446
- "StreamsInbound": 128,
447
- "StreamsOutbound": 256,
448
- "Conns": 64,
449
- "ConnsInbound": 32,
450
- "ConnsOutbound": 64,
451
- "FD": 64,
452
- "Memory": 33554432
453
- },
454
- "ServiceDefault": {
455
- "Streams": 4096,
456
- "StreamsInbound": 1024,
457
- "StreamsOutbound": 4096,
458
- "Conns": 0,
459
- "ConnsInbound": 0,
460
- "ConnsOutbound": 0,
461
- "FD": 0,
462
- "Memory": 67108864
463
- },
464
- "Service": {
465
- "libp2p.autonat": {
466
- "Streams": 64,
467
- "StreamsInbound": 64,
468
- "StreamsOutbound": 64,
469
- "Conns": 0,
470
- "ConnsInbound": 0,
471
- "ConnsOutbound": 0,
472
- "FD": 0,
473
- "Memory": 4194304
474
- },
475
- "libp2p.holepunch": {
476
- "Streams": 64,
477
- "StreamsInbound": 32,
478
- "StreamsOutbound": 32,
479
- "Conns": 0,
480
- "ConnsInbound": 0,
481
- "ConnsOutbound": 0,
482
- "FD": 0,
483
- "Memory": 4194304
484
- },
485
- "libp2p.identify": {
486
- "Streams": 128,
487
- "StreamsInbound": 64,
488
- "StreamsOutbound": 64,
489
- "Conns": 0,
490
- "ConnsInbound": 0,
491
- "ConnsOutbound": 0,
492
- "FD": 0,
493
- "Memory": 4194304
494
- },
495
- "libp2p.ping": {
496
- "Streams": 64,
497
- "StreamsInbound": 64,
498
- "StreamsOutbound": 64,
499
- "Conns": 0,
500
- "ConnsInbound": 0,
501
- "ConnsOutbound": 0,
502
- "FD": 0,
503
- "Memory": 4194304
504
- },
505
- "libp2p.relay/v1": {
506
- "Streams": 256,
507
- "StreamsInbound": 256,
508
- "StreamsOutbound": 256,
509
- "Conns": 0,
510
- "ConnsInbound": 0,
511
- "ConnsOutbound": 0,
512
- "FD": 0,
513
- "Memory": 16777216
514
- },
515
- "libp2p.relay/v2": {
516
- "Streams": 256,
517
- "StreamsInbound": 256,
518
- "StreamsOutbound": 256,
519
- "Conns": 0,
520
- "ConnsInbound": 0,
521
- "ConnsOutbound": 0,
522
- "FD": 0,
523
- "Memory": 16777216
524
- }
525
- },
526
- "ServicePeerDefault": {
527
- "Streams": 256,
528
- "StreamsInbound": 128,
529
- "StreamsOutbound": 256,
530
- "Conns": 0,
531
- "ConnsInbound": 0,
532
- "ConnsOutbound": 0,
533
- "FD": 0,
534
- "Memory": 16777216
535
- },
536
- "ServicePeer": {
537
- "libp2p.autonat": {
538
- "Streams": 2,
539
- "StreamsInbound": 2,
540
- "StreamsOutbound": 2,
541
- "Conns": 0,
542
- "ConnsInbound": 0,
543
- "ConnsOutbound": 0,
544
- "FD": 0,
545
- "Memory": 1048576
546
- },
547
- "libp2p.holepunch": {
548
- "Streams": 2,
549
- "StreamsInbound": 2,
550
- "StreamsOutbound": 2,
551
- "Conns": 0,
552
- "ConnsInbound": 0,
553
- "ConnsOutbound": 0,
554
- "FD": 0,
555
- "Memory": 1048576
556
- },
557
- "libp2p.identify": {
558
- "Streams": 32,
559
- "StreamsInbound": 16,
560
- "StreamsOutbound": 16,
561
- "Conns": 0,
562
- "ConnsInbound": 0,
563
- "ConnsOutbound": 0,
564
- "FD": 0,
565
- "Memory": 1048576
566
- },
567
- "libp2p.ping": {
568
- "Streams": 4,
569
- "StreamsInbound": 2,
570
- "StreamsOutbound": 3,
571
- "Conns": 0,
572
- "ConnsInbound": 0,
573
- "ConnsOutbound": 0,
574
- "FD": 0,
575
- "Memory": 8590458880
576
- },
577
- "libp2p.relay/v1": {
578
- "Streams": 64,
579
- "StreamsInbound": 64,
580
- "StreamsOutbound": 64,
581
- "Conns": 0,
582
- "ConnsInbound": 0,
583
- "ConnsOutbound": 0,
584
- "FD": 0,
585
- "Memory": 1048576
586
- },
587
- "libp2p.relay/v2": {
588
- "Streams": 64,
589
- "StreamsInbound": 64,
590
- "StreamsOutbound": 64,
591
- "Conns": 0,
592
- "ConnsInbound": 0,
593
- "ConnsOutbound": 0,
594
- "FD": 0,
595
- "Memory": 1048576
596
- }
597
- },
598
- "ProtocolDefault": {
599
- "Streams": 2048,
600
- "StreamsInbound": 512,
601
- "StreamsOutbound": 2048,
602
- "Conns": 0,
603
- "ConnsInbound": 0,
604
- "ConnsOutbound": 0,
605
- "FD": 0,
606
- "Memory": 67108864
607
- },
608
- "Protocol": {
609
- "/ipfs/id/1.0.0": {
610
- "Streams": 128,
611
- "StreamsInbound": 64,
612
- "StreamsOutbound": 64,
613
- "Conns": 0,
614
- "ConnsInbound": 0,
615
- "ConnsOutbound": 0,
616
- "FD": 0,
617
- "Memory": 4194304
618
- },
619
- "/ipfs/id/push/1.0.0": {
620
- "Streams": 128,
621
- "StreamsInbound": 64,
622
- "StreamsOutbound": 64,
623
- "Conns": 0,
624
- "ConnsInbound": 0,
625
- "ConnsOutbound": 0,
626
- "FD": 0,
627
- "Memory": 4194304
628
- },
629
- "/ipfs/ping/1.0.0": {
630
- "Streams": 64,
631
- "StreamsInbound": 64,
632
- "StreamsOutbound": 64,
633
- "Conns": 0,
634
- "ConnsInbound": 0,
635
- "ConnsOutbound": 0,
636
- "FD": 0,
637
- "Memory": 4194304
638
- },
639
- "/libp2p/autonat/1.0.0": {
640
- "Streams": 64,
641
- "StreamsInbound": 64,
642
- "StreamsOutbound": 64,
643
- "Conns": 0,
644
- "ConnsInbound": 0,
645
- "ConnsOutbound": 0,
646
- "FD": 0,
647
- "Memory": 4194304
648
- },
649
- "/libp2p/circuit/relay/0.1.0": {
650
- "Streams": 640,
651
- "StreamsInbound": 640,
652
- "StreamsOutbound": 640,
653
- "Conns": 0,
654
- "ConnsInbound": 0,
655
- "ConnsOutbound": 0,
656
- "FD": 0,
657
- "Memory": 16777216
658
- },
659
- "/libp2p/circuit/relay/0.2.0/hop": {
660
- "Streams": 640,
661
- "StreamsInbound": 640,
662
- "StreamsOutbound": 640,
663
- "Conns": 0,
664
- "ConnsInbound": 0,
665
- "ConnsOutbound": 0,
666
- "FD": 0,
667
- "Memory": 16777216
668
- },
669
- "/libp2p/circuit/relay/0.2.0/stop": {
670
- "Streams": 640,
671
- "StreamsInbound": 640,
672
- "StreamsOutbound": 640,
673
- "Conns": 0,
674
- "ConnsInbound": 0,
675
- "ConnsOutbound": 0,
676
- "FD": 0,
677
- "Memory": 16777216
678
- },
679
- "/libp2p/dcutr": {
680
- "Streams": 64,
681
- "StreamsInbound": 32,
682
- "StreamsOutbound": 32,
683
- "Conns": 0,
684
- "ConnsInbound": 0,
685
- "ConnsOutbound": 0,
686
- "FD": 0,
687
- "Memory": 4194304
688
- },
689
- "/p2p/id/delta/1.0.0": {
690
- "Streams": 128,
691
- "StreamsInbound": 64,
692
- "StreamsOutbound": 64,
693
- "Conns": 0,
694
- "ConnsInbound": 0,
695
- "ConnsOutbound": 0,
696
- "FD": 0,
697
- "Memory": 4194304
698
- }
699
- },
700
- "ProtocolPeerDefault": {
701
- "Streams": 256,
702
- "StreamsInbound": 64,
703
- "StreamsOutbound": 128,
704
- "Conns": 0,
705
- "ConnsInbound": 0,
706
- "ConnsOutbound": 0,
707
- "FD": 0,
708
- "Memory": 16777216
709
- },
710
- "ProtocolPeer": {
711
- "/ipfs/id/1.0.0": {
712
- "Streams": 32,
713
- "StreamsInbound": 16,
714
- "StreamsOutbound": 16,
715
- "Conns": 0,
716
- "ConnsInbound": 0,
717
- "ConnsOutbound": 0,
718
- "FD": 0,
719
- "Memory": 8590458880
720
- },
721
- "/ipfs/id/push/1.0.0": {
722
- "Streams": 32,
723
- "StreamsInbound": 16,
724
- "StreamsOutbound": 16,
725
- "Conns": 0,
726
- "ConnsInbound": 0,
727
- "ConnsOutbound": 0,
728
- "FD": 0,
729
- "Memory": 8590458880
730
- },
731
- "/ipfs/ping/1.0.0": {
732
- "Streams": 4,
733
- "StreamsInbound": 2,
734
- "StreamsOutbound": 3,
735
- "Conns": 0,
736
- "ConnsInbound": 0,
737
- "ConnsOutbound": 0,
738
- "FD": 0,
739
- "Memory": 8590458880
740
- },
741
- "/libp2p/autonat/1.0.0": {
742
- "Streams": 2,
743
- "StreamsInbound": 2,
744
- "StreamsOutbound": 2,
745
- "Conns": 0,
746
- "ConnsInbound": 0,
747
- "ConnsOutbound": 0,
748
- "FD": 0,
749
- "Memory": 1048576
750
- },
751
- "/libp2p/circuit/relay/0.1.0": {
752
- "Streams": 128,
753
- "StreamsInbound": 128,
754
- "StreamsOutbound": 128,
755
- "Conns": 0,
756
- "ConnsInbound": 0,
757
- "ConnsOutbound": 0,
758
- "FD": 0,
759
- "Memory": 33554432
760
- },
761
- "/libp2p/circuit/relay/0.2.0/hop": {
762
- "Streams": 128,
763
- "StreamsInbound": 128,
764
- "StreamsOutbound": 128,
765
- "Conns": 0,
766
- "ConnsInbound": 0,
767
- "ConnsOutbound": 0,
768
- "FD": 0,
769
- "Memory": 33554432
770
- },
771
- "/libp2p/circuit/relay/0.2.0/stop": {
772
- "Streams": 128,
773
- "StreamsInbound": 128,
774
- "StreamsOutbound": 128,
775
- "Conns": 0,
776
- "ConnsInbound": 0,
777
- "ConnsOutbound": 0,
778
- "FD": 0,
779
- "Memory": 33554432
780
- },
781
- "/libp2p/dcutr": {
782
- "Streams": 2,
783
- "StreamsInbound": 2,
784
- "StreamsOutbound": 2,
785
- "Conns": 0,
786
- "ConnsInbound": 0,
787
- "ConnsOutbound": 0,
788
- "FD": 0,
789
- "Memory": 1048576
790
- },
791
- "/p2p/id/delta/1.0.0": {
792
- "Streams": 32,
793
- "StreamsInbound": 16,
794
- "StreamsOutbound": 16,
795
- "Conns": 0,
796
- "ConnsInbound": 0,
797
- "ConnsOutbound": 0,
798
- "FD": 0,
799
- "Memory": 8590458880
800
- }
801
- },
802
- "PeerDefault": {
803
- "Streams": 512,
804
- "StreamsInbound": 256,
805
- "StreamsOutbound": 512,
806
- "Conns": 8,
807
- "ConnsInbound": 4,
808
- "ConnsOutbound": 8,
809
- "FD": 4,
810
- "Memory": 67108864
811
- },
812
- "Conn": {
813
- "Streams": 0,
814
- "StreamsInbound": 0,
815
- "StreamsOutbound": 0,
816
- "Conns": 1,
817
- "ConnsInbound": 1,
818
- "ConnsOutbound": 1,
819
- "FD": 1,
820
- "Memory": 1048576
821
- },
822
- "Stream": {
823
- "Streams": 1,
824
- "StreamsInbound": 1,
825
- "StreamsOutbound": 1,
826
- "Conns": 0,
827
- "ConnsInbound": 0,
828
- "ConnsOutbound": 0,
829
- "FD": 0,
830
- "Memory": 16777216
831
- }
832
-}`
207
+ return defaultLimitConfig, nil
208
+}