Просмотр исходного кода

Use cidrranger instead of patricia

tags/v2.1.5^2
9seconds 4 лет назад
Родитель
Сommit
d467fba674
3 измененных файлов: 46 добавлений и 75 удалений
  1. 4
    2
      go.mod
  2. 2
    3
      go.sum
  3. 40
    70
      ipblocklist/firehol.go

+ 4
- 2
go.mod Просмотреть файл

12
 	github.com/golang/protobuf v1.5.2 // indirect
12
 	github.com/golang/protobuf v1.5.2 // indirect
13
 	github.com/gotd/td v0.34.0
13
 	github.com/gotd/td v0.34.0
14
 	github.com/jarcoal/httpmock v1.0.8
14
 	github.com/jarcoal/httpmock v1.0.8
15
-	github.com/kentik/patricia v0.0.0-20210909164817-21603333b70e
16
 	github.com/mccutchen/go-httpbin v1.1.1
15
 	github.com/mccutchen/go-httpbin v1.1.1
17
 	github.com/panjf2000/ants/v2 v2.4.7
16
 	github.com/panjf2000/ants/v2 v2.4.7
18
 	github.com/pelletier/go-toml v1.9.4
17
 	github.com/pelletier/go-toml v1.9.4
30
 	google.golang.org/protobuf v1.27.1 // indirect
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
 require (
37
 require (
36
 	github.com/beorn7/perks v1.0.1 // indirect
38
 	github.com/beorn7/perks v1.0.1 // indirect

+ 2
- 3
go.sum Просмотреть файл

169
 github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
169
 github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
170
 github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
170
 github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
171
 github.com/k0kubun/pp v2.4.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
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
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
172
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
175
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
173
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
176
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
174
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
245
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
243
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
246
 github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As=
244
 github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As=
247
 github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
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
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
246
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
250
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
247
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
251
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
248
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
260
 github.com/txthinking/x v0.0.0-20210326105829-476fab902fbe/go.mod h1:WgqbSEmUYSjEV3B1qmee/PpP2NYEz4bL9/+mF1ma+s4=
257
 github.com/txthinking/x v0.0.0-20210326105829-476fab902fbe/go.mod h1:WgqbSEmUYSjEV3B1qmee/PpP2NYEz4bL9/+mF1ma+s4=
261
 github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43 h1:QEePdg0ty2r0t1+qwfZmQ4OOl/MB2UXIeJSpIZv56lg=
258
 github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43 h1:QEePdg0ty2r0t1+qwfZmQ4OOl/MB2UXIeJSpIZv56lg=
262
 github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43/go.mod h1:OYRfF6eb5wY9VRFkXJH8FFBi3plw2v+giaIu7P054pM=
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
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
262
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
264
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
263
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
265
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
264
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=

+ 40
- 70
ipblocklist/firehol.go Просмотреть файл

12
 
12
 
13
 	"github.com/9seconds/mtg/v2/ipblocklist/files"
13
 	"github.com/9seconds/mtg/v2/ipblocklist/files"
14
 	"github.com/9seconds/mtg/v2/mtglib"
14
 	"github.com/9seconds/mtg/v2/mtglib"
15
-	"github.com/kentik/patricia"
16
-	"github.com/kentik/patricia/bool_tree"
17
 	"github.com/panjf2000/ants/v2"
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
 // Firehol is IPBlocklist which uses lists from FireHOL:
26
 // Firehol is IPBlocklist which uses lists from FireHOL:
28
 // https://iplists.firehol.org/
27
 // https://iplists.firehol.org/
43
 	logger      mtglib.Logger
42
 	logger      mtglib.Logger
44
 	updateMutex sync.RWMutex
43
 	updateMutex sync.RWMutex
45
 
44
 
45
+	ranger cidranger.Ranger
46
+
46
 	blocklists []files.File
47
 	blocklists []files.File
47
 
48
 
48
 	workerPool *ants.Pool
49
 	workerPool *ants.Pool
49
-	treeV4     *bool_tree.TreeV4
50
-	treeV6     *bool_tree.TreeV6
51
 }
50
 }
52
 
51
 
53
 // Shutdown stop a background update process.
52
 // Shutdown stop a background update process.
64
 	f.updateMutex.RLock()
63
 	f.updateMutex.RLock()
65
 	defer f.updateMutex.RUnlock()
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
 // Run starts a background update process.
74
 // Run starts a background update process.
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
 func (f *Firehol) update() {
106
 func (f *Firehol) update() {
127
 	ctx, cancel := context.WithCancel(f.ctx)
107
 	ctx, cancel := context.WithCancel(f.ctx)
128
 	defer cancel()
108
 	defer cancel()
131
 	wg.Add(len(f.blocklists))
111
 	wg.Add(len(f.blocklists))
132
 
112
 
133
 	treeMutex := &sync.Mutex{}
113
 	treeMutex := &sync.Mutex{}
134
-	v4tree := bool_tree.NewTreeV4()
135
-	v6tree := bool_tree.NewTreeV6()
114
+	ranger := cidranger.NewPCTrieRanger()
136
 
115
 
137
 	for _, v := range f.blocklists {
116
 	for _, v := range f.blocklists {
138
 		go func(file files.File) {
117
 		go func(file files.File) {
149
 
128
 
150
 			defer fileContent.Close()
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
 				logger.WarningError("update has failed", err)
132
 				logger.WarningError("update has failed", err)
154
 			}
133
 			}
155
 		}(v)
134
 		}(v)
160
 	f.updateMutex.Lock()
139
 	f.updateMutex.Lock()
161
 	defer f.updateMutex.Unlock()
140
 	defer f.updateMutex.Unlock()
162
 
141
 
163
-	f.treeV4 = v4tree
164
-	f.treeV6 = v6tree
142
+	f.ranger = ranger
165
 
143
 
166
 	f.logger.Info("ip list was updated")
144
 	f.logger.Info("ip list was updated")
167
 }
145
 }
168
 
146
 
169
 func (f *Firehol) updateFromFile(mutex sync.Locker,
147
 func (f *Firehol) updateFromFile(mutex sync.Locker,
170
-	v4tree *bool_tree.TreeV4,
171
-	v6tree *bool_tree.TreeV6,
148
+	ranger cidranger.Ranger,
172
 	scanner *bufio.Scanner) error {
149
 	scanner *bufio.Scanner) error {
173
 	for scanner.Scan() {
150
 	for scanner.Scan() {
174
 		text := scanner.Text()
151
 		text := scanner.Text()
179
 			continue
156
 			continue
180
 		}
157
 		}
181
 
158
 
182
-		ip, cidr, err := f.updateParseLine(text)
159
+		ipnet, err := f.updateParseLine(text)
183
 		if err != nil {
160
 		if err != nil {
184
 			return fmt.Errorf("cannot parse a line: %w", err)
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
 	if scanner.Err() != nil {
173
 	if scanner.Err() != nil {
194
 	return nil
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
 // NewFirehol creates a new instance of FireHOL IP blocklist.
202
 // NewFirehol creates a new instance of FireHOL IP blocklist.
275
 		ctx:        ctx,
246
 		ctx:        ctx,
276
 		ctxCancel:  cancel,
247
 		ctxCancel:  cancel,
277
 		logger:     logger.Named("firehol"),
248
 		logger:     logger.Named("firehol"),
278
-		treeV4:     bool_tree.NewTreeV4(),
279
-		treeV6:     bool_tree.NewTreeV6(),
249
+		ranger:     cidranger.NewPCTrieRanger(),
280
 		workerPool: workerPool,
250
 		workerPool: workerPool,
281
 		blocklists: blocklists,
251
 		blocklists: blocklists,
282
 	}, nil
252
 	}, nil

Загрузка…
Отмена
Сохранить