-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfilter.go
148 lines (121 loc) · 3.36 KB
/
filter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package main
import (
"net"
"regexp"
)
// RequestFilter decides whether to reject a Request/Response.
type RequestFilter interface {
Reject(Request) bool
}
// RequestFilterFunc wraps a function so that it implements thi Filter interface.
type RequestFilterFunc func(Request) bool
// Reject runs f on the Request.
func (f RequestFilterFunc) Reject(r Request) bool {
return f(r)
}
// ResultFilter decides whether to reject a Result.
type ResultFilter interface {
Reject(Result) bool
}
// ResultFilterFunc wraps a function so that it implements thi Filter interface.
type ResultFilterFunc func(Result) bool
// Reject runs f on the Result.
func (f ResultFilterFunc) Reject(r Result) bool {
return f(r)
}
// ResponseFilter decides whether to reject a Response.
type ResponseFilter interface {
Reject(Response) bool
}
// ResponseFilterFunc wraps a function so that it implements thi Filter interface.
type ResponseFilterFunc func(Response) bool
// Reject runs f on the Response.
func (f ResponseFilterFunc) Reject(r Response) bool {
return f(r)
}
// FilterNotFound returns a filter which hides "not found" responses.
func FilterNotFound() RequestFilter {
return RequestFilterFunc(func(r Request) (reject bool) {
return r.NotFound
})
}
// FilterInSubnet returns a filter which hides responses with addresses in one
// of the subnets.
func FilterInSubnet(subnets []*net.IPNet) ResponseFilter {
return ResponseFilterFunc(func(res Response) (reject bool) {
// don't process anything except v4/v6 responses
if res.Type != "A" && res.Type != "AAAA" {
return false
}
ip := net.ParseIP(res.Data)
if ip == nil {
return false
}
for _, subnet := range subnets {
if subnet.Contains(ip) {
return true
}
}
return false
})
}
// FilterNotInSubnet returns a filter which hides responses with addresses
// which are not in one of the subnets.
func FilterNotInSubnet(subnets []*net.IPNet) ResponseFilter {
return ResponseFilterFunc(func(res Response) (reject bool) {
// don't process anything except v4/v6 responses
if res.Type != "A" && res.Type != "AAAA" {
return false
}
ip := net.ParseIP(res.Data)
if ip == nil {
return false
}
for _, subnet := range subnets {
if subnet.Contains(ip) {
return false
}
}
return true
})
}
// FilterEmptyResults returns a filter which hides responses.
func FilterEmptyResults() ResultFilter {
return ResultFilterFunc(func(r Result) (reject bool) {
return r.Empty()
})
}
// FilterDelegations returns a filter which hides potential delegations.
func FilterDelegations() ResultFilter {
return ResultFilterFunc(func(r Result) (reject bool) {
return r.Delegation()
})
}
// FilterRejectCNAMEs return a filter which hides cnames matching any of the patterns.
func FilterRejectCNAMEs(patterns []*regexp.Regexp) ResponseFilter {
return ResponseFilterFunc(func(r Response) (reject bool) {
if r.Type != "CNAME" {
return false
}
for _, pat := range patterns {
if pat.Match([]byte(r.Data)) {
return true
}
}
return false
})
}
// FilterRejectPTR returns a filter which hides PTR responses matching one of the patterns.
func FilterRejectPTR(patterns []*regexp.Regexp) ResponseFilter {
return ResponseFilterFunc(func(r Response) (reject bool) {
if r.Type != "PTR" {
return false
}
for _, pat := range patterns {
if pat.Match([]byte(r.Data)) {
return true
}
}
return false
})
}