main.go 2.42 KB
Newer Older
1 2 3
package main

import (
4 5
	"flag"
	"fmt"
Frank Denis's avatar
Frank Denis committed
6
	"os"
7
	"sync"
8

Frank Denis's avatar
Frank Denis committed
9
	"github.com/facebookgo/pidfile"
Frank Denis's avatar
Frank Denis committed
10
	"github.com/jedisct1/dlog"
11
	"github.com/kardianos/service"
12 13
)

14
const (
Frank Denis's avatar
Frank Denis committed
15
	AppVersion            = "2.0.19"
Frank Denis's avatar
Frank Denis committed
16
	DefaultConfigFileName = "dnscrypt-proxy.toml"
17
)
18

19
type App struct {
20 21 22
	wg    sync.WaitGroup
	quit  chan struct{}
	proxy Proxy
23 24
}

Frank Denis's avatar
Frank Denis committed
25
func main() {
26
	dlog.Init("dnscrypt-proxy", dlog.SeverityNotice, "DAEMON")
27

Frank Denis's avatar
Frank Denis committed
28
	pwd, err := os.Getwd()
29
	if err != nil {
Frank Denis's avatar
Frank Denis committed
30
		dlog.Fatal("Unable to find the path to the current directory")
31
	}
32
	svcConfig := &service.Config{
Frank Denis's avatar
Frank Denis committed
33 34 35 36
		Name:             "dnscrypt-proxy",
		DisplayName:      "DNSCrypt client proxy",
		Description:      "Encrypted/authenticated DNS proxy",
		WorkingDirectory: pwd,
37 38
	}
	svcFlag := flag.String("service", "", fmt.Sprintf("Control the system service: %q", service.ControlAction))
39
	app := &App{}
40 41
	svc, err := service.New(app, svcConfig)
	if err != nil {
42 43
		svc = nil
		dlog.Debug(err)
44
	}
45
	app.proxy = NewProxy()
46
	_ = ServiceManagerStartNotify()
Frank Denis's avatar
Frank Denis committed
47
	if err := ConfigLoad(&app.proxy, svcFlag); err != nil {
48 49
		dlog.Fatal(err)
	}
Frank Denis's avatar
Frank Denis committed
50
	dlog.Noticef("dnscrypt-proxy %s", AppVersion)
51

52
	if len(*svcFlag) != 0 {
53 54 55
		if svc == nil {
			dlog.Fatal("Built-in service installation is not supported on this platform")
		}
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
		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
	}
72 73 74 75 76 77
	if svc != nil {
		if err = svc.Run(); err != nil {
			dlog.Fatal(err)
		}
	} else {
		app.Start(nil)
Frank Denis's avatar
Frank Denis committed
78
	}
79 80 81
}

func (app *App) Start(service service.Service) error {
Frank Denis's avatar
Frank Denis committed
82 83
	proxy := &app.proxy
	if err := InitPluginsGlobals(&proxy.pluginsGlobals, proxy); err != nil {
84 85
		dlog.Fatal(err)
	}
86 87
	app.quit = make(chan struct{})
	app.wg.Add(1)
88 89
	if service != nil {
		go func() {
Frank Denis's avatar
Frank Denis committed
90
			app.AppMain(proxy)
91 92
		}()
	} else {
Frank Denis's avatar
Frank Denis committed
93
		app.AppMain(proxy)
94
	}
95
	return nil
96 97
}

98
func (app *App) AppMain(proxy *Proxy) {
Frank Denis's avatar
Frank Denis committed
99
	pidfile.Write()
100
	proxy.StartProxy()
101 102 103
	<-app.quit
	dlog.Notice("Quit signal received...")
	app.wg.Done()
Frank Denis's avatar
Frank Denis committed
104

105 106
}

107
func (app *App) Stop(service service.Service) error {
Frank Denis's avatar
Frank Denis committed
108 109 110
	if pidFilePath := pidfile.GetPidfilePath(); len(pidFilePath) > 1 {
		os.Remove(pidFilePath)
	}
111 112
	dlog.Notice("Stopped.")
	return nil
113
}