Skip to content

Commit 192ac0f

Browse files
authored
absorb go-maddr-filter; rm stale Makefile targets; upgrade deps (#124)
1 parent 8ae68cf commit 192ac0f

File tree

5 files changed

+385
-28
lines changed

5 files changed

+385
-28
lines changed

Diff for: Makefile

+1-15
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,3 @@
1-
gx:
2-
go get github.com/whyrusleeping/gx
3-
go get github.com/whyrusleeping/gx-go
4-
5-
covertools:
6-
go get golang.org/x/tools/cmd/cover
7-
8-
deps: gx covertools
9-
gx --verbose install --global
10-
gx-go rewrite
11-
12-
publish:
13-
gx-go rewrite --undo
14-
151
conformance: tmp/multiaddr
162
go build -o tmp/multiaddr/test/go-multiaddr ./multiaddr
173
cd tmp/multiaddr/test && MULTIADDR_BIN="./go-multiaddr" go test -v
@@ -23,4 +9,4 @@ tmp/multiaddr:
239
clean:
2410
rm -rf tmp/
2511

26-
.PHONY: gx covertools deps publish conformance clean
12+
.PHONY: conformance clean

Diff for: filter.go

+179
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
package multiaddr
2+
3+
import (
4+
"net"
5+
"sync"
6+
)
7+
8+
// Action is an enum modelling all possible filter actions.
9+
type Action int32
10+
11+
const (
12+
ActionNone Action = iota // zero value.
13+
ActionAccept
14+
ActionDeny
15+
)
16+
17+
type filterEntry struct {
18+
f net.IPNet
19+
action Action
20+
}
21+
22+
// Filters is a structure representing a collection of accept/deny
23+
// net.IPNet filters, together with the DefaultAction flag, which
24+
// represents the default filter policy.
25+
//
26+
// Note that the last policy added to the Filters is authoritative.
27+
type Filters struct {
28+
DefaultAction Action
29+
30+
mu sync.RWMutex
31+
filters []*filterEntry
32+
}
33+
34+
// NewFilters constructs and returns a new set of net.IPNet filters.
35+
// By default, the new filter accepts all addresses.
36+
func NewFilters() *Filters {
37+
return &Filters{
38+
DefaultAction: ActionAccept,
39+
filters: make([]*filterEntry, 0),
40+
}
41+
}
42+
43+
func (fs *Filters) find(ipnet net.IPNet) (int, *filterEntry) {
44+
s := ipnet.String()
45+
for idx, ft := range fs.filters {
46+
if ft.f.String() == s {
47+
return idx, ft
48+
}
49+
}
50+
return -1, nil
51+
}
52+
53+
// AddDialFilter adds a deny rule to this Filters set. Hosts
54+
// matching the given net.IPNet filter will be denied, unless
55+
// another rule is added which states that they should be accepted.
56+
//
57+
// No effort is made to prevent duplication of filters, or to simplify
58+
// the filters list.
59+
//
60+
// Deprecated: Use AddFilter().
61+
func (fs *Filters) AddDialFilter(f *net.IPNet) {
62+
fs.AddFilter(*f, ActionDeny)
63+
}
64+
65+
// AddFilter adds a rule to the Filters set, enforcing the desired action for
66+
// the provided IPNet mask.
67+
func (fs *Filters) AddFilter(ipnet net.IPNet, action Action) {
68+
fs.mu.Lock()
69+
defer fs.mu.Unlock()
70+
71+
if _, f := fs.find(ipnet); f != nil {
72+
f.action = action
73+
} else {
74+
fs.filters = append(fs.filters, &filterEntry{ipnet, action})
75+
}
76+
}
77+
78+
// RemoveLiteral removes the first filter associated with the supplied IPNet,
79+
// returning whether something was removed or not. It makes no distinction
80+
// between whether the rule is an accept or a deny.
81+
//
82+
// Deprecated: use RemoveLiteral() instead.
83+
func (fs *Filters) Remove(ipnet *net.IPNet) (removed bool) {
84+
return fs.RemoveLiteral(*ipnet)
85+
}
86+
87+
// RemoveLiteral removes the first filter associated with the supplied IPNet,
88+
// returning whether something was removed or not. It makes no distinction
89+
// between whether the rule is an accept or a deny.
90+
func (fs *Filters) RemoveLiteral(ipnet net.IPNet) (removed bool) {
91+
fs.mu.Lock()
92+
defer fs.mu.Unlock()
93+
94+
if idx, _ := fs.find(ipnet); idx != -1 {
95+
fs.filters = append(fs.filters[:idx], fs.filters[idx+1:]...)
96+
return true
97+
}
98+
return false
99+
}
100+
101+
// AddrBlocked parses a ma.Multiaddr and, if a valid netip is found, it applies the
102+
// Filter set rules, returning true if the given address should be denied, and false if
103+
// the given address is accepted.
104+
//
105+
// If a parsing error occurs, or no filter matches, the Filters'
106+
// default is returned.
107+
//
108+
// TODO: currently, the last filter to match wins always, but it shouldn't be that way.
109+
// Instead, the highest-specific last filter should win; that way more specific filters
110+
// override more general ones.
111+
func (fs *Filters) AddrBlocked(a Multiaddr) (deny bool) {
112+
var (
113+
netip net.IP
114+
found bool
115+
)
116+
117+
ForEach(a, func(c Component) bool {
118+
switch c.Protocol().Code {
119+
case P_IP6ZONE:
120+
return true
121+
case P_IP6, P_IP4:
122+
found = true
123+
netip = net.IP(c.RawValue())
124+
return false
125+
default:
126+
return false
127+
}
128+
})
129+
130+
if !found {
131+
return fs.DefaultAction == ActionDeny
132+
}
133+
134+
fs.mu.RLock()
135+
defer fs.mu.RUnlock()
136+
137+
action := fs.DefaultAction
138+
for _, ft := range fs.filters {
139+
if ft.f.Contains(netip) {
140+
action = ft.action
141+
}
142+
}
143+
144+
return action == ActionDeny
145+
}
146+
147+
// Filters returns the list of DENY net.IPNet masks. For backwards compatibility.
148+
//
149+
// A copy of the filters is made prior to returning, so the inner state is not exposed.
150+
//
151+
// Deprecated: Use FiltersForAction().
152+
func (fs *Filters) Filters() (result []*net.IPNet) {
153+
ffa := fs.FiltersForAction(ActionDeny)
154+
for _, res := range ffa {
155+
res := res // allocate a new copy
156+
result = append(result, &res)
157+
}
158+
return result
159+
}
160+
161+
func (fs *Filters) ActionForFilter(ipnet net.IPNet) (action Action, ok bool) {
162+
if _, f := fs.find(ipnet); f != nil {
163+
return f.action, true
164+
}
165+
return ActionNone, false
166+
}
167+
168+
// FiltersForAction returns the filters associated with the indicated action.
169+
func (fs *Filters) FiltersForAction(action Action) (result []net.IPNet) {
170+
fs.mu.RLock()
171+
defer fs.mu.RUnlock()
172+
173+
for _, ff := range fs.filters {
174+
if ff.action == action {
175+
result = append(result, ff.f)
176+
}
177+
}
178+
return result
179+
}

0 commit comments

Comments
 (0)