-
Notifications
You must be signed in to change notification settings - Fork 107
/
main.go
145 lines (123 loc) · 3.62 KB
/
main.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
package main
import (
"context"
"flag"
"log"
"net/http"
"os"
"os/signal"
"runtime"
"syscall"
"time"
"github.com/elico/drbl-peer"
)
var (
configPath string
forceUpdate bool
grimdActive bool
grimdActivation *ActivationHandler
drblPeers *drblpeer.DrblPeers
)
func reloadBlockCache(config *Config,
blockCache *MemoryBlockCache,
questionCache *MemoryQuestionCache,
drblPeers *drblpeer.DrblPeers,
apiServer *http.Server,
server *Server,
reloadChan chan bool) (*MemoryBlockCache, *http.Server, error) {
logger.Debug("Reloading the blockcache")
blockCache = PerformUpdate(config, true)
server.Stop()
if apiServer != nil {
if err := apiServer.Shutdown(context.Background()); err != nil {
logger.Debugf("error shutting down api server: %v", err)
}
}
server.Run(config, blockCache, questionCache)
apiServer, err := StartAPIServer(config, reloadChan, blockCache, questionCache)
if err != nil {
logger.Fatal(err)
return nil, nil, err
}
if config.UseDrbl > 0 {
drblPeers, _ = drblpeer.NewPeerListFromYamlFile(config.DrblPeersFilename, config.DrblBlockWeight, config.DrblTimeout, config.DrblDebug > 0)
if config.DrblDebug > 0 {
log.Println("Drbl Debug is ON")
drblPeers.Debug = true
log.Println("Drbl Debug is ON", drblPeers.Debug)
}
}
return blockCache, apiServer, nil
}
func main() {
flag.Parse()
config, err := LoadConfig(configPath)
if err != nil {
logger.Fatal(err)
}
loggingState, err := loggerInit(config.LogConfig)
if err != nil {
logger.Fatal(err)
}
defer func() {
loggingState.cleanUp()
}()
grimdActive = true
quitActivation := make(chan bool)
actChannel := make(chan *ActivationHandler)
go startActivation(actChannel, quitActivation, config.ReactivationDelay)
grimdActivation = <-actChannel
close(actChannel)
server := &Server{
host: config.Bind,
rTimeout: 5 * time.Second,
wTimeout: 5 * time.Second,
}
// BlockCache contains all blocked domains
blockCache := &MemoryBlockCache{Backend: make(map[string]bool)}
// QuestionCache contains all queries to the dns server
questionCache := makeQuestionCache(config.QuestionCacheCap)
reloadChan := make(chan bool)
// The server will start with an empty blockcache soe we can dowload the lists if grimd is the
// system's dns server.
server.Run(config, blockCache, questionCache)
var apiServer *http.Server
// Load the block cache, restart the server with the new context
blockCache, apiServer, err = reloadBlockCache(config, blockCache, questionCache, drblPeers, apiServer, server, reloadChan)
if err != nil {
logger.Fatalf("Cannot start the API server %s", err)
}
sig := make(chan os.Signal)
signal.Notify(sig, os.Interrupt, syscall.SIGHUP)
forever:
for {
select {
case s := <-sig:
switch s {
case os.Interrupt:
logger.Error("SIGINT received, stopping\n")
quitActivation <- true
break forever
case syscall.SIGHUP:
logger.Error("SIGHUP received: rotating logs\n")
err := loggingState.reopen()
if err != nil {
logger.Error(err)
}
}
case <-reloadChan:
blockCache, apiServer, err = reloadBlockCache(config, blockCache, questionCache, drblPeers, apiServer, server, reloadChan)
if err != nil {
logger.Fatalf("Cannot start the API server %s", err)
}
}
}
// make sure we give the activation goroutine time to exit
<-quitActivation
logger.Debugf("Main goroutine exiting")
}
func init() {
flag.StringVar(&configPath, "config", "grimd.toml", "location of the config file, if not found it will be generated (default grimd.toml)")
flag.BoolVar(&forceUpdate, "update", false, "force an update of the blocklist database")
runtime.GOMAXPROCS(runtime.NumCPU())
}