Browse Source

fix #1842

Warn about banning a single IPv6 address
tags/v2.9.0-rc1
Shivaram Lingamneni 2 years ago
parent
commit
fd45529d94
3 changed files with 54 additions and 1 deletions
  1. 8
    0
      irc/flatip/flatip.go
  2. 34
    0
      irc/flatip/flatip_test.go
  3. 12
    1
      irc/uban.go

+ 8
- 0
irc/flatip/flatip.go View File

@@ -155,6 +155,14 @@ func (cidr IPNet) Contains(ip IP) bool {
155 155
 	return cidr.IP == maskedIP
156 156
 }
157 157
 
158
+func (cidr IPNet) Size() (ones, bits int) {
159
+	if cidr.IP.IsIPv4() {
160
+		return int(cidr.PrefixLen) - 96, 32
161
+	} else {
162
+		return int(cidr.PrefixLen), 128
163
+	}
164
+}
165
+
158 166
 // FromNetIPnet converts a net.IPNet into an IPNet.
159 167
 func FromNetIPNet(network net.IPNet) (result IPNet) {
160 168
 	ones, _ := network.Mask.Size()

+ 34
- 0
irc/flatip/flatip_test.go View File

@@ -2,8 +2,10 @@ package flatip
2 2
 
3 3
 import (
4 4
 	"bytes"
5
+	"fmt"
5 6
 	"math/rand"
6 7
 	"net"
8
+	"reflect"
7 9
 	"testing"
8 10
 	"time"
9 11
 )
@@ -86,6 +88,38 @@ func doMaskingTest(ip net.IP, t *testing.T) {
86 88
 	}
87 89
 }
88 90
 
91
+func assertEqual(found, expected interface{}) {
92
+	if !reflect.DeepEqual(found, expected) {
93
+		panic(fmt.Sprintf("expected %#v, found %#v", expected, found))
94
+	}
95
+}
96
+
97
+func TestSize(t *testing.T) {
98
+	_, net, err := ParseCIDR("8.8.8.8/24")
99
+	if err != nil {
100
+		panic(err)
101
+	}
102
+	ones, bits := net.Size()
103
+	assertEqual(ones, 24)
104
+	assertEqual(bits, 32)
105
+
106
+	_, net, err = ParseCIDR("2001::0db8/64")
107
+	if err != nil {
108
+		panic(err)
109
+	}
110
+	ones, bits = net.Size()
111
+	assertEqual(ones, 64)
112
+	assertEqual(bits, 128)
113
+
114
+	_, net, err = ParseCIDR("2001::0db8/96")
115
+	if err != nil {
116
+		panic(err)
117
+	}
118
+	ones, bits = net.Size()
119
+	assertEqual(ones, 96)
120
+	assertEqual(bits, 128)
121
+}
122
+
89 123
 func TestMasking(t *testing.T) {
90 124
 	for _, ipstr := range testIPStrs {
91 125
 		doMaskingTest(easyParseIP(ipstr), t)

+ 12
- 1
irc/uban.go View File

@@ -366,7 +366,14 @@ func ubanInfoHandler(client *Client, target ubanTarget, params []string, rb *Res
366 366
 }
367 367
 
368 368
 func ubanInfoCIDR(client *Client, target ubanTarget, rb *ResponseBuffer) {
369
-	if target.cidr.PrefixLen == 128 {
369
+	config := client.server.Config()
370
+	// show connection limiter/throttler state if this CIDR is entirely
371
+	// contained in a single limiter/throttler bucket:
372
+	ones, bits := target.cidr.Size()
373
+	showLimiter := (bits == 32 && ones >= config.Server.IPLimits.CidrLenIPv4) ||
374
+		(bits == 128 && ones >= config.Server.IPLimits.CidrLenIPv6)
375
+	sendMaskWarning := (bits == 128 && ones > config.Server.IPLimits.CidrLenIPv6)
376
+	if showLimiter {
370 377
 		netName, status := client.server.connectionLimiter.Status(target.cidr.IP)
371 378
 		if status.Exempt {
372 379
 			rb.Notice(fmt.Sprintf(client.t("IP %s is exempt from connection limits"), target.cidr.IP.String()))
@@ -391,6 +398,10 @@ func ubanInfoCIDR(client *Client, target ubanTarget, rb *ResponseBuffer) {
391 398
 			rb.Notice(line)
392 399
 		}
393 400
 	}
401
+	if sendMaskWarning {
402
+		rb.Notice(fmt.Sprintf(client.t("Note: try evaluating a wider IPv6 CIDR like %s/%d"),
403
+			target.cidr.IP.String(), config.Server.IPLimits.CidrLenIPv6))
404
+	}
394 405
 }
395 406
 
396 407
 func ubanInfoNickmask(client *Client, target ubanTarget, rb *ResponseBuffer) {

Loading…
Cancel
Save