dnscrypt-proxy/dnscrypt-proxy/main.go

132 lines
2.8 KiB
Go
Raw Normal View History

package main
import (
crypto_rand "crypto/rand"
"encoding/binary"
2018-01-17 11:28:43 +01:00
"flag"
"fmt"
"math/rand"
2018-02-28 18:11:48 +01:00
"os"
"os/signal"
"sync"
"syscall"
2018-02-28 18:11:48 +01:00
"github.com/facebookgo/pidfile"
2018-01-11 11:50:54 +01:00
"github.com/jedisct1/dlog"
2018-01-17 11:28:43 +01:00
"github.com/kardianos/service"
)
const (
2019-10-28 12:18:51 +01:00
AppVersion = "2.0.29"
2018-01-31 08:38:22 +01:00
DefaultConfigFileName = "dnscrypt-proxy.toml"
)
type App struct {
2018-01-17 11:28:43 +01:00
wg sync.WaitGroup
quit chan struct{}
2019-10-09 17:59:46 +02:00
proxy *Proxy
}
2018-01-09 13:35:10 +01:00
func main() {
dlog.Init("dnscrypt-proxy", dlog.SeverityNotice, "DAEMON")
os.Setenv("GODEBUG", os.Getenv("GODEBUG")+",tls13=1")
seed := make([]byte, 8)
crypto_rand.Read(seed)
rand.Seed(int64(binary.LittleEndian.Uint64(seed[:])))
pwd, err := os.Getwd()
if err != nil {
dlog.Fatal("Unable to find the path to the current directory")
}
2018-01-17 11:28:43 +01:00
svcConfig := &service.Config{
Name: "dnscrypt-proxy",
DisplayName: "DNSCrypt client proxy",
Description: "Encrypted/authenticated DNS proxy",
WorkingDirectory: pwd,
2018-01-17 11:28:43 +01:00
}
svcFlag := flag.String("service", "", fmt.Sprintf("Control the system service: %q", service.ControlAction))
app := &App{
quit: make(chan struct{}),
}
2018-01-17 11:28:43 +01:00
svc, err := service.New(app, svcConfig)
if err != nil {
svc = nil
dlog.Debug(err)
}
app.proxy = NewProxy()
_ = ServiceManagerStartNotify()
2018-01-17 11:28:43 +01:00
if len(*svcFlag) != 0 {
if svc == nil {
dlog.Fatal("Built-in service installation is not supported on this platform")
}
2018-01-17 11:28:43 +01:00
if err := service.Control(svc, *svcFlag); err != nil {
dlog.Fatal(err)
}
if *svcFlag == "install" {
dlog.Notice("Installed as a service. Use `-service start` to start")
} else if *svcFlag == "uninstall" {
dlog.Notice("Service uninstalled")
} else if *svcFlag == "start" {
dlog.Notice("Service started")
} else if *svcFlag == "stop" {
dlog.Notice("Service stopped")
} else if *svcFlag == "restart" {
dlog.Notice("Service restarted")
}
return
}
app.wg.Add(1)
if svc != nil {
if err = svc.Run(); err != nil {
dlog.Fatal(err)
}
} else {
if err := ConfigLoad(app.proxy); err != nil {
dlog.Fatal(err)
}
app.signalWatch()
app.appMain()
2018-01-10 12:01:49 +01:00
}
app.wg.Wait()
dlog.Notice("Stopped.")
2018-01-17 11:28:43 +01:00
}
func (app *App) Start(service service.Service) error {
go func() {
if err := ConfigLoad(app.proxy); err != nil {
dlog.Fatal(err)
}
if err := app.proxy.InitPluginsGlobals(); err != nil {
dlog.Fatal(err)
}
app.appMain()
}()
return nil
}
func (app *App) Stop(service service.Service) error {
if pidFilePath := pidfile.GetPidfilePath(); len(pidFilePath) > 1 {
os.Remove(pidFilePath)
}
dlog.Notice("Quit signal received...")
close(app.quit)
return nil
}
func (app *App) appMain() {
2018-02-28 18:11:48 +01:00
pidfile.Write()
app.proxy.StartProxy(app.quit)
app.wg.Done()
}
func (app *App) signalWatch() {
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-quit
signal.Stop(quit)
close(app.quit)
}()
2018-01-14 00:56:46 +01:00
}