main.go 2.36 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
	"time"
9

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

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

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

Frank Denis's avatar
Frank Denis committed
26
func main() {
27
	dlog.Init("dnscrypt-proxy", dlog.SeverityNotice, "DAEMON")
28 29 30 31 32 33
	svcConfig := &service.Config{
		Name:        "dnscrypt-proxy",
		DisplayName: "DNSCrypt client proxy",
		Description: "Encrypted/authenticated DNS proxy",
	}
	svcFlag := flag.String("service", "", fmt.Sprintf("Control the system service: %q", service.ControlAction))
34
	app := &App{}
35 36
	svc, err := service.New(app, svcConfig)
	if err != nil {
37 38
		svc = nil
		dlog.Debug(err)
39
	}
40
	app.proxy = NewProxy()
41
	app.proxy.xTransport = NewXTransport(30*time.Second, true, false)
42

Frank Denis's avatar
Frank Denis committed
43
	if err := ConfigLoad(&app.proxy, svcFlag); err != nil {
44 45
		dlog.Fatal(err)
	}
Frank Denis's avatar
Frank Denis committed
46
	dlog.Noticef("dnscrypt-proxy %s", AppVersion)
47

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

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

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

104 105
}

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