/
lookup.go
129 lines (108 loc) Β· 3.54 KB
/
lookup.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
package filterlists
import (
"errors"
"net"
"github.com/safing/portbase/database"
"github.com/safing/portbase/log"
)
// lookupBlockLists loads the entity record for key from
// cache and returns the list of blocklist sources the
// key is part of. It is not considered an error if
// key does not exist, instead, an empty slice is
// returned.
func lookupBlockLists(entity, value string) ([]string, error) {
key := makeListCacheKey(entity, value)
if !isLoaded() {
log.Warningf("intel/filterlists: not searching for %s because filterlists not loaded", key)
// filterLists have not yet been loaded so
// there's no point querying into the cache
// database.
return nil, nil
}
filterListLock.RLock()
defer filterListLock.RUnlock()
if !defaultFilter.test(entity, value) {
return nil, nil
}
// log.Debugf("intel/filterlists: searching for entries with %s", key)
entry, err := getEntityRecordByKey(key)
if err != nil {
if errors.Is(err, database.ErrNotFound) {
return nil, nil
}
log.Errorf("intel/filterlists: failed to get entries for key %s: %s", key, err)
return nil, err
}
return entry.Sources, nil
}
// LookupCountry returns a list of sources that mark the country
// as blocked. If country is not stored in the cache database
// a nil slice is returned.
func LookupCountry(country string) ([]string, error) {
return lookupBlockLists("country", country)
}
// LookupDomain returns a list of sources that mark the domain
// as blocked. If domain is not stored in the cache database
// a nil slice is returned. The caller is responsible for making
// sure that the given domain is valid and canonical.
func LookupDomain(domain string) ([]string, error) {
switch domain {
case "", ".":
// Return no lists for empty domains and the root zone.
return nil, nil
default:
return lookupBlockLists("domain", domain)
}
}
// LookupASNString returns a list of sources that mark the ASN
// as blocked. If ASN is not stored in the cache database
// a nil slice is returned.
func LookupASNString(asn string) ([]string, error) {
return lookupBlockLists("asn", asn)
}
// LookupIP returns a list of block sources that contain
// a reference to ip. LookupIP automatically checks the IPv4 or
// IPv6 lists respectively.
func LookupIP(ip net.IP) ([]string, error) {
if ip.To4() == nil {
return LookupIPv6(ip)
}
return LookupIPv4(ip)
}
// LookupIPString is like LookupIP but accepts an IPv4 or
// IPv6 address in their string representations.
func LookupIPString(ipStr string) ([]string, error) {
ip := net.ParseIP(ipStr)
if ip == nil {
return nil, errors.New("invalid IP")
}
return LookupIP(ip)
}
// LookupIPv4String returns a list of block sources that
// contain a reference to ip. If the IP is not stored in the
// cache database a nil slice is returned.
func LookupIPv4String(ipv4 string) ([]string, error) {
return lookupBlockLists("ipv4", ipv4)
}
// LookupIPv4 is like LookupIPv4String but accepts a net.IP.
func LookupIPv4(ipv4 net.IP) ([]string, error) {
ip := ipv4.To4()
if ip == nil {
return nil, errors.New("invalid IPv4")
}
return LookupIPv4String(ip.String())
}
// LookupIPv6String returns a list of block sources that
// contain a reference to ip. If the IP is not stored in the
// cache database a nil slice is returned.
func LookupIPv6String(ipv6 string) ([]string, error) {
return lookupBlockLists("ipv6", ipv6)
}
// LookupIPv6 is like LookupIPv6String but accepts a net.IP.
func LookupIPv6(ipv6 net.IP) ([]string, error) {
ip := ipv6.To16()
if ip == nil {
return nil, errors.New("invalid IPv6")
}
return LookupIPv6String(ip.String())
}