Przeglądaj źródła

fix #1421

Allow custom limit definitions that encompass multiple subnets
tags/v2.5.0-rc1
Shivaram Lingamneni 3 lat temu
rodzic
commit
f9b842c88b

+ 16
- 6
default.yaml Wyświetl plik

@@ -263,13 +263,23 @@ server:
263 263
             # - "192.168.1.1"
264 264
             # - "2001:0db8::/32"
265 265
 
266
-        # custom connection limits for certain IPs/networks. note that CIDR
267
-        # widths defined here override the default CIDR width --- the limit
268
-        # will apply to the entire CIDR no matter how large or small it is
266
+        # custom connection limits for certain IPs/networks.
269 267
         custom-limits:
270
-            # "8.8.0.0/16":
271
-            #     max-concurrent-connections: 128
272
-            #     max-connections-per-window: 1024
268
+            #"irccloud":
269
+            #    nets:
270
+            #        - "192.184.9.108"  # highgate.irccloud.com
271
+            #        - "192.184.9.110"  # ealing.irccloud.com
272
+            #        - "192.184.9.112"  # charlton.irccloud.com
273
+            #        - "192.184.10.118" # brockwell.irccloud.com
274
+            #        - "192.184.10.9"   # tooting.irccloud.com
275
+            #        - "192.184.8.73"   # hathersage.irccloud.com
276
+            #        - "192.184.8.103"  # stonehaven.irccloud.com
277
+            #        - "5.254.36.57"    # tinside.irccloud.com
278
+            #        - "5.254.36.56/29" # additional ipv4 net
279
+            #        - "2001:67c:2f08::/48"
280
+            #        - "2a03:5180:f::/64"
281
+            #    max-concurrent-connections: 2048
282
+            #    max-connections-per-window: 2048
273 283
 
274 284
     # pluggable IP ban mechanism, via subprocess invocation
275 285
     # this can be used to check new connections against a DNSBL, for example

+ 30
- 10
irc/connection_limits/limiter.go Wyświetl plik

@@ -19,14 +19,17 @@ var (
19 19
 )
20 20
 
21 21
 type CustomLimitConfig struct {
22
+	Nets          []string
22 23
 	MaxConcurrent int `yaml:"max-concurrent-connections"`
23 24
 	MaxPerWindow  int `yaml:"max-connections-per-window"`
24 25
 }
25 26
 
26 27
 // tuples the key-value pair of a CIDR and its custom limit/throttle values
27 28
 type customLimit struct {
28
-	CustomLimitConfig
29
-	ipNet net.IPNet
29
+	name          string
30
+	maxConcurrent int
31
+	maxPerWindow  int
32
+	nets          []net.IPNet
30 33
 }
31 34
 
32 35
 // LimiterConfig controls the automated connection limits.
@@ -71,14 +74,29 @@ func (config *LimiterConfig) postprocess() (err error) {
71 74
 		return fmt.Errorf("Could not parse limiter exemption list: %v", err.Error())
72 75
 	}
73 76
 
74
-	for netStr, customLimitConf := range config.CustomLimits {
75
-		normalizedNet, err := utils.NormalizedNetFromString(netStr)
76
-		if err != nil {
77
-			return fmt.Errorf("Could not parse custom limit specification: %v", err.Error())
77
+	for identifier, customLimitConf := range config.CustomLimits {
78
+		nets := make([]net.IPNet, len(customLimitConf.Nets))
79
+		for i, netStr := range customLimitConf.Nets {
80
+			normalizedNet, err := utils.NormalizedNetFromString(netStr)
81
+			if err != nil {
82
+				return fmt.Errorf("Bad net %s in custom-limits block %s: %w", netStr, identifier, err)
83
+			}
84
+			nets[i] = normalizedNet
85
+		}
86
+		if len(customLimitConf.Nets) == 0 {
87
+			// see #1421: this is the legacy config format where the
88
+			// dictionary key of the block is a CIDR string
89
+			normalizedNet, err := utils.NormalizedNetFromString(identifier)
90
+			if err != nil {
91
+				return fmt.Errorf("Custom limit block %s has no defined nets", identifier)
92
+			}
93
+			nets = []net.IPNet{normalizedNet}
78 94
 		}
79 95
 		config.customLimits = append(config.customLimits, customLimit{
80
-			CustomLimitConfig: customLimitConf,
81
-			ipNet:             normalizedNet,
96
+			maxConcurrent: customLimitConf.MaxConcurrent,
97
+			maxPerWindow:  customLimitConf.MaxPerWindow,
98
+			name:          "*" + identifier,
99
+			nets:          nets,
82 100
 		})
83 101
 	}
84 102
 
@@ -105,8 +123,10 @@ type Limiter struct {
105 123
 func (cl *Limiter) addrToKey(addr net.IP) (key string, limit int, throttle int) {
106 124
 	// `key` will be a CIDR string like "8.8.8.8/32" or "2001:0db8::/32"
107 125
 	for _, custom := range cl.config.customLimits {
108
-		if custom.ipNet.Contains(addr) {
109
-			return custom.ipNet.String(), custom.MaxConcurrent, custom.MaxPerWindow
126
+		for _, net := range custom.nets {
127
+			if net.Contains(addr) {
128
+				return custom.name, custom.maxConcurrent, custom.maxPerWindow
129
+			}
110 130
 		}
111 131
 	}
112 132
 

+ 3
- 2
irc/connection_limits/limiter_test.go Wyświetl plik

@@ -32,7 +32,8 @@ var baseConfig = LimiterConfig{
32 32
 		Exempted: []string{"localhost"},
33 33
 
34 34
 		CustomLimits: map[string]CustomLimitConfig{
35
-			"8.8.0.0/16": {
35
+			"google": {
36
+				Nets:          []string{"8.8.0.0/16"},
36 37
 				MaxConcurrent: 128,
37 38
 				MaxPerWindow:  256,
38 39
 			},
@@ -57,7 +58,7 @@ func TestKeying(t *testing.T) {
57 58
 	assertEqual(maxWin, 8, t)
58 59
 
59 60
 	key, maxConc, maxWin = limiter.addrToKey(easyParseIP("8.8.4.4"))
60
-	assertEqual(key, "8.8.0.0/16", t)
61
+	assertEqual(key, "*google", t)
61 62
 	assertEqual(maxConc, 128, t)
62 63
 	assertEqual(maxWin, 256, t)
63 64
 }

+ 16
- 6
traditional.yaml Wyświetl plik

@@ -236,13 +236,23 @@ server:
236 236
             # - "192.168.1.1"
237 237
             # - "2001:0db8::/32"
238 238
 
239
-        # custom connection limits for certain IPs/networks. note that CIDR
240
-        # widths defined here override the default CIDR width --- the limit
241
-        # will apply to the entire CIDR no matter how large or small it is
239
+        # custom connection limits for certain IPs/networks.
242 240
         custom-limits:
243
-            # "8.8.0.0/16":
244
-            #     max-concurrent-connections: 128
245
-            #     max-connections-per-window: 1024
241
+            #"irccloud":
242
+            #    nets:
243
+            #        - "192.184.9.108"  # highgate.irccloud.com
244
+            #        - "192.184.9.110"  # ealing.irccloud.com
245
+            #        - "192.184.9.112"  # charlton.irccloud.com
246
+            #        - "192.184.10.118" # brockwell.irccloud.com
247
+            #        - "192.184.10.9"   # tooting.irccloud.com
248
+            #        - "192.184.8.73"   # hathersage.irccloud.com
249
+            #        - "192.184.8.103"  # stonehaven.irccloud.com
250
+            #        - "5.254.36.57"    # tinside.irccloud.com
251
+            #        - "5.254.36.56/29" # additional ipv4 net
252
+            #        - "2001:67c:2f08::/48"
253
+            #        - "2a03:5180:f::/64"
254
+            #    max-concurrent-connections: 2048
255
+            #    max-connections-per-window: 2048
246 256
 
247 257
     # pluggable IP ban mechanism, via subprocess invocation
248 258
     # this can be used to check new connections against a DNSBL, for example

Ładowanie…
Anuluj
Zapisz