Parcourir la source

Merge pull request #254 from 9seconds/cidranger

Use cidrranger instead of patricia
tags/v2.1.5^2
Sergey Arkhipov il y a 4 ans
Parent
révision
4687a7c899
Aucun compte lié à l'adresse e-mail de l'auteur
3 fichiers modifiés avec 46 ajouts et 75 suppressions
  1. 4
    2
      go.mod
  2. 2
    3
      go.sum
  3. 40
    70
      ipblocklist/firehol.go

+ 4
- 2
go.mod Voir le fichier

@@ -12,7 +12,6 @@ require (
12 12
 	github.com/golang/protobuf v1.5.2 // indirect
13 13
 	github.com/gotd/td v0.34.0
14 14
 	github.com/jarcoal/httpmock v1.0.8
15
-	github.com/kentik/patricia v0.0.0-20210909164817-21603333b70e
16 15
 	github.com/mccutchen/go-httpbin v1.1.1
17 16
 	github.com/panjf2000/ants/v2 v2.4.7
18 17
 	github.com/pelletier/go-toml v1.9.4
@@ -30,7 +29,10 @@ require (
30 29
 	google.golang.org/protobuf v1.27.1 // indirect
31 30
 )
32 31
 
33
-require github.com/txthinking/socks5 v0.0.0-20211121111206-e03c1217a50b
32
+require (
33
+	github.com/txthinking/socks5 v0.0.0-20211121111206-e03c1217a50b
34
+	github.com/yl2chen/cidranger v1.0.2
35
+)
34 36
 
35 37
 require (
36 38
 	github.com/beorn7/perks v1.0.1 // indirect

+ 2
- 3
go.sum Voir le fichier

@@ -169,8 +169,6 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
169 169
 github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
170 170
 github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
171 171
 github.com/k0kubun/pp v2.4.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
172
-github.com/kentik/patricia v0.0.0-20210909164817-21603333b70e h1:1wAVuGu1c+lsdaOPQN+9xoP9+gaIMJV6H0ehGc+K5iA=
173
-github.com/kentik/patricia v0.0.0-20210909164817-21603333b70e/go.mod h1:2OfLA+0esiUJpwMjrH39pEk79cb8MvGTBS9YlZpejJ4=
174 172
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
175 173
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
176 174
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -245,7 +243,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
245 243
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
246 244
 github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As=
247 245
 github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
248
-github.com/stretchr/testify v1.1.5-0.20170809224252-890a5c3458b4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
249 246
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
250 247
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
251 248
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -260,6 +257,8 @@ github.com/txthinking/x v0.0.0-20210326105829-476fab902fbe h1:gMWxZxBFRAXqoGkwkY
260 257
 github.com/txthinking/x v0.0.0-20210326105829-476fab902fbe/go.mod h1:WgqbSEmUYSjEV3B1qmee/PpP2NYEz4bL9/+mF1ma+s4=
261 258
 github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43 h1:QEePdg0ty2r0t1+qwfZmQ4OOl/MB2UXIeJSpIZv56lg=
262 259
 github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43/go.mod h1:OYRfF6eb5wY9VRFkXJH8FFBi3plw2v+giaIu7P054pM=
260
+github.com/yl2chen/cidranger v1.0.2 h1:lbOWZVCG1tCRX4u24kuM1Tb4nHqWkDxwLdoS+SevawU=
261
+github.com/yl2chen/cidranger v1.0.2/go.mod h1:9U1yz7WPYDwf0vpNWFaeRh0bjwz5RVgRy/9UEQfHl0g=
263 262
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
264 263
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
265 264
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=

+ 40
- 70
ipblocklist/firehol.go Voir le fichier

@@ -12,17 +12,16 @@ import (
12 12
 
13 13
 	"github.com/9seconds/mtg/v2/ipblocklist/files"
14 14
 	"github.com/9seconds/mtg/v2/mtglib"
15
-	"github.com/kentik/patricia"
16
-	"github.com/kentik/patricia/bool_tree"
17 15
 	"github.com/panjf2000/ants/v2"
16
+	"github.com/yl2chen/cidranger"
18 17
 )
19 18
 
20
-const (
21
-	fireholIPv4DefaultCIDR = 32
22
-	fireholIPv6DefaultCIDR = 128
23
-)
19
+var (
20
+	fireholRegexpComment = regexp.MustCompile(`\s*#.*?$`)
24 21
 
25
-var fireholRegexpComment = regexp.MustCompile(`\s*#.*?$`)
22
+	fireholIPv4DefaultCIDR = net.CIDRMask(32, 32)   // nolint: gomnd
23
+	fireholIPv6DefaultCIDR = net.CIDRMask(128, 128) // nolint: gomnd
24
+)
26 25
 
27 26
 // Firehol is IPBlocklist which uses lists from FireHOL:
28 27
 // https://iplists.firehol.org/
@@ -43,11 +42,11 @@ type Firehol struct {
43 42
 	logger      mtglib.Logger
44 43
 	updateMutex sync.RWMutex
45 44
 
45
+	ranger cidranger.Ranger
46
+
46 47
 	blocklists []files.File
47 48
 
48 49
 	workerPool *ants.Pool
49
-	treeV4     *bool_tree.TreeV4
50
-	treeV6     *bool_tree.TreeV6
51 50
 }
52 51
 
53 52
 // Shutdown stop a background update process.
@@ -64,11 +63,12 @@ func (f *Firehol) Contains(ip net.IP) bool {
64 63
 	f.updateMutex.RLock()
65 64
 	defer f.updateMutex.RUnlock()
66 65
 
67
-	if ip4 := ip.To4(); ip4 != nil {
68
-		return f.containsIPv4(ip4)
66
+	ok, err := f.ranger.Contains(ip)
67
+	if err != nil {
68
+		f.logger.BindStr("ip", ip.String()).DebugError("Cannot check if ip is present", err)
69 69
 	}
70 70
 
71
-	return f.containsIPv6(ip.To16())
71
+	return ok && err == nil
72 72
 }
73 73
 
74 74
 // Run starts a background update process.
@@ -103,26 +103,6 @@ func (f *Firehol) Run(updateEach time.Duration) {
103 103
 	}
104 104
 }
105 105
 
106
-func (f *Firehol) containsIPv4(addr net.IP) bool {
107
-	ip := patricia.NewIPv4AddressFromBytes(addr, 32) // nolint: gomnd
108
-
109
-	if ok, _ := f.treeV4.FindDeepestTag(ip); ok {
110
-		return true
111
-	}
112
-
113
-	return false
114
-}
115
-
116
-func (f *Firehol) containsIPv6(addr net.IP) bool {
117
-	ip := patricia.NewIPv6Address(addr, 128) // nolint: gomnd
118
-
119
-	if ok, _ := f.treeV6.FindDeepestTag(ip); ok {
120
-		return true
121
-	}
122
-
123
-	return false
124
-}
125
-
126 106
 func (f *Firehol) update() {
127 107
 	ctx, cancel := context.WithCancel(f.ctx)
128 108
 	defer cancel()
@@ -131,8 +111,7 @@ func (f *Firehol) update() {
131 111
 	wg.Add(len(f.blocklists))
132 112
 
133 113
 	treeMutex := &sync.Mutex{}
134
-	v4tree := bool_tree.NewTreeV4()
135
-	v6tree := bool_tree.NewTreeV6()
114
+	ranger := cidranger.NewPCTrieRanger()
136 115
 
137 116
 	for _, v := range f.blocklists {
138 117
 		go func(file files.File) {
@@ -149,7 +128,7 @@ func (f *Firehol) update() {
149 128
 
150 129
 			defer fileContent.Close()
151 130
 
152
-			if err := f.updateFromFile(treeMutex, v4tree, v6tree, bufio.NewScanner(fileContent)); err != nil {
131
+			if err := f.updateFromFile(treeMutex, ranger, bufio.NewScanner(fileContent)); err != nil {
153 132
 				logger.WarningError("update has failed", err)
154 133
 			}
155 134
 		}(v)
@@ -160,15 +139,13 @@ func (f *Firehol) update() {
160 139
 	f.updateMutex.Lock()
161 140
 	defer f.updateMutex.Unlock()
162 141
 
163
-	f.treeV4 = v4tree
164
-	f.treeV6 = v6tree
142
+	f.ranger = ranger
165 143
 
166 144
 	f.logger.Info("ip list was updated")
167 145
 }
168 146
 
169 147
 func (f *Firehol) updateFromFile(mutex sync.Locker,
170
-	v4tree *bool_tree.TreeV4,
171
-	v6tree *bool_tree.TreeV6,
148
+	ranger cidranger.Ranger,
172 149
 	scanner *bufio.Scanner) error {
173 150
 	for scanner.Scan() {
174 151
 		text := scanner.Text()
@@ -179,12 +156,18 @@ func (f *Firehol) updateFromFile(mutex sync.Locker,
179 156
 			continue
180 157
 		}
181 158
 
182
-		ip, cidr, err := f.updateParseLine(text)
159
+		ipnet, err := f.updateParseLine(text)
183 160
 		if err != nil {
184 161
 			return fmt.Errorf("cannot parse a line: %w", err)
185 162
 		}
186 163
 
187
-		f.updateAddToTrees(ip, cidr, mutex, v4tree, v6tree)
164
+		mutex.Lock()
165
+		err = ranger.Insert(cidranger.NewBasicRangerEntry(*ipnet))
166
+		mutex.Unlock()
167
+
168
+		if err != nil {
169
+			return fmt.Errorf("cannot insert %v into ranger: %w", ipnet, err)
170
+		}
188 171
 	}
189 172
 
190 173
 	if scanner.Err() != nil {
@@ -194,38 +177,26 @@ func (f *Firehol) updateFromFile(mutex sync.Locker,
194 177
 	return nil
195 178
 }
196 179
 
197
-func (f *Firehol) updateParseLine(text string) (net.IP, uint, error) {
198
-	_, ipnet, err := net.ParseCIDR(text)
199
-	if err != nil {
200
-		ipaddr := net.ParseIP(text)
201
-		if ipaddr == nil {
202
-			return nil, 0, fmt.Errorf("incorrect ip address %s", text)
203
-		}
204
-
205
-		ip4 := ipaddr.To4()
206
-		if ip4 != nil {
207
-			return ip4, fireholIPv4DefaultCIDR, nil
208
-		}
209
-
210
-		return ipaddr.To16(), fireholIPv6DefaultCIDR, nil
180
+func (f *Firehol) updateParseLine(text string) (*net.IPNet, error) {
181
+	if _, ipnet, err := net.ParseCIDR(text); err == nil {
182
+		return ipnet, nil
211 183
 	}
212 184
 
213
-	ones, _ := ipnet.Mask.Size()
214
-
215
-	return ipnet.IP, uint(ones), nil
216
-}
185
+	ipaddr := net.ParseIP(text)
186
+	if ipaddr == nil {
187
+		return nil, fmt.Errorf("incorrect ip address %s", text)
188
+	}
217 189
 
218
-func (f *Firehol) updateAddToTrees(ip net.IP, cidr uint,
219
-	mutex sync.Locker,
220
-	v4tree *bool_tree.TreeV4, v6tree *bool_tree.TreeV6) {
221
-	mutex.Lock()
222
-	defer mutex.Unlock()
190
+	mask := fireholIPv4DefaultCIDR
223 191
 
224
-	if ip.To4() != nil {
225
-		v4tree.Set(patricia.NewIPv4AddressFromBytes(ip, cidr), true)
226
-	} else {
227
-		v6tree.Set(patricia.NewIPv6Address(ip, cidr), true)
192
+	if ipaddr.To4() == nil {
193
+		mask = fireholIPv6DefaultCIDR
228 194
 	}
195
+
196
+	return &net.IPNet{
197
+		IP:   ipaddr,
198
+		Mask: mask,
199
+	}, nil
229 200
 }
230 201
 
231 202
 // NewFirehol creates a new instance of FireHOL IP blocklist.
@@ -275,8 +246,7 @@ func NewFireholFromFiles(logger mtglib.Logger,
275 246
 		ctx:        ctx,
276 247
 		ctxCancel:  cancel,
277 248
 		logger:     logger.Named("firehol"),
278
-		treeV4:     bool_tree.NewTreeV4(),
279
-		treeV6:     bool_tree.NewTreeV6(),
249
+		ranger:     cidranger.NewPCTrieRanger(),
280 250
 		workerPool: workerPool,
281 251
 		blocklists: blocklists,
282 252
 	}, nil

Chargement…
Annuler
Enregistrer