-
Notifications
You must be signed in to change notification settings - Fork 5
/
block_domains_decider_abp.go
106 lines (88 loc) · 2.61 KB
/
block_domains_decider_abp.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
package blocker
import (
"bufio"
"os"
"strings"
"time"
"github.com/miekg/dns"
)
type BlockDomainsDeciderABP struct {
blocklist map[string]bool
blocklistFile string
lastUpdated time.Time
log Logger
}
// Name ...
func NewBlockDomainsDeciderABP(filePath string, logger Logger) BlockDomainsDecider {
return &BlockDomainsDeciderABP{
blocklistFile: filePath,
log: logger,
blocklist: map[string]bool{},
}
}
// IsDomainBlocked ...
func (d *BlockDomainsDeciderABP) IsDomainBlocked(domain string) bool {
// We will check every subdomain of the given domain against the blocklist. i.e. if example.com
// is blocked, then every subdomain of that (subdomain.example.com, sub1.sub2.example.com) is
// blocked. However, example.com.org is not blocked.
comps := strings.Split(domain, ".")
current := comps[len(comps)-1]
for i := len(comps) - 2; i >= 0; i-- {
newCurrent := strings.Join([]string{
comps[i],
current,
}, ".")
if d.blocklist[newCurrent] {
return true
}
current = newCurrent
}
return false
}
// StartBlocklistUpdater ...
func (d *BlockDomainsDeciderABP) StartBlocklistUpdater(ticker *time.Ticker) {
go func() {
for {
tick := <-ticker.C
d.log.Debugf("Ticker arrived at time: %v", tick)
if d.IsBlocklistUpdateRequired() {
d.log.Debug("update required")
d.UpdateBlocklist()
} else {
d.log.Debug("update not required")
}
}
}()
}
// UpdateBlocklist ...
func (d *BlockDomainsDeciderABP) UpdateBlocklist() error {
// Update process
blocklistContent, err := os.Open(d.blocklistFile)
if err != nil {
d.log.Errorf("could not read blocklist file: %s", d.blocklistFile)
return err
}
defer blocklistContent.Close()
numBlockedDomainsBefore := len(d.blocklist)
lastUpdatedBefore := d.lastUpdated
scanner := bufio.NewScanner(blocklistContent)
for scanner.Scan() {
hostLine := scanner.Text()
if !strings.HasPrefix(hostLine, "||") || !strings.HasSuffix(hostLine, "^") {
d.log.Warningf("line \"%s\" does not match parseable ABP syntax subset", hostLine)
continue
}
hostLine = strings.TrimPrefix(hostLine, "||")
hostLine = strings.TrimSuffix(hostLine, "^")
d.blocklist[dns.Fqdn(hostLine)] = true
}
d.lastUpdated = time.Now()
d.log.Infof("updated blocklist; blocked domains: before: %d, after: %d; last updated: before: %v, after: %v",
numBlockedDomainsBefore, len(d.blocklist), lastUpdatedBefore, d.lastUpdated)
return nil
}
// IsBlocklistUpdateRequired ...
func (d *BlockDomainsDeciderABP) IsBlocklistUpdateRequired() bool {
blocklistFileStat, _ := os.Stat(d.blocklistFile)
return blocklistFileStat.ModTime().After(d.lastUpdated)
}