Skip to content

Commit

Permalink
GUI -> background service
Browse files Browse the repository at this point in the history
  • Loading branch information
Regentag committed Feb 12, 2019
1 parent 08b4c48 commit 5fb5139
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 167 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ test.out
a.out
*.syso
*.exe
*.log
2 changes: 0 additions & 2 deletions build.bat

This file was deleted.

2 changes: 0 additions & 2 deletions clean.bat

This file was deleted.

9 changes: 0 additions & 9 deletions comctrl6.manifest

This file was deleted.

14 changes: 8 additions & 6 deletions doh_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (e *DohError) Error() string {
return e.msg
}

func NewErr(msg string) error {
func newErr(msg string) error {
return &DohError{msg}
}

Expand All @@ -46,7 +46,7 @@ func makeHttpsRequest(wire []byte) (respWire []byte, err error) {
defer resp.Body.Close()

if resp.StatusCode != 200 {
return nil, NewErr("HTTP error code " + resp.Status)
return nil, newErr("HTTP error code " + resp.Status)
}

respBody, err := ioutil.ReadAll(resp.Body)
Expand Down Expand Up @@ -114,14 +114,14 @@ func getDohHostAddr() (*dns.Msg, error) {
return r, err
}

type SvrStopFunc func()
type SvrStopFunc func() error
type SvrErrorHandlerFunc func(err error)

func RunDNS(port int, errHandler SvrErrorHandlerFunc) (SvrStopFunc, error) {
// get DOH host address
h, e := getDohHostAddr()
if e != nil {
return nil, NewErr("Failed to lookup Cloudflare DOH server address. " +
return nil, newErr("Failed to lookup Cloudflare DOH server address. " +
e.Error())
}

Expand All @@ -137,9 +137,11 @@ func RunDNS(port int, errHandler SvrErrorHandlerFunc) (SvrStopFunc, error) {
}
}()

return func() {
return func() error {
if srv != nil {
srv.Shutdown()
return srv.Shutdown()
} else {
return newErr("No DNS server instance.")
}
}, nil
}
13 changes: 13 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module github.com/Regentag/SecureDNS

require (
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/jimlawless/whereami v0.0.0-20160417220522-aebf70d4a772
github.com/miekg/dns v1.1.3
golang.org/x/crypto v0.0.0-20190122013713-64072686203f // indirect
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 // indirect
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
golang.org/x/sys v0.0.0-20190122071731-054c452bb702
gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/yaml.v2 v2.2.2 // indirect
)
20 changes: 20 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/jimlawless/whereami v0.0.0-20160417220522-aebf70d4a772 h1:AmdJkqc+PNWRgFZH/W9W5HbSt5L42ZJaG3LBqIA8D/M=
github.com/jimlawless/whereami v0.0.0-20160417220522-aebf70d4a772/go.mod h1:O5/I95fNj2n4v8dVHc/XX/rv4i9P5AAr0koHbBkPnh8=
github.com/miekg/dns v1.1.3 h1:1g0r1IvskvgL8rR+AcHzUA+oFmGcQlaIm4IqakufeMM=
github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
golang.org/x/crypto v0.0.0-20190122013713-64072686203f h1:u1CmMhe3a44hy8VIgpInORnI01UVaUYheqR7x9BxT3c=
golang.org/x/crypto v0.0.0-20190122013713-64072686203f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 h1:ulvT7fqt0yHWzpJwI57MezWnYDVpCAYBVuYst/L+fAY=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190122071731-054c452bb702 h1:Lk4tbZFnlyPgV+sLgTw5yGfzrlOn9kx4vSombi2FFlY=
golang.org/x/sys v0.0.0-20190122071731-054c452bb702/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
Binary file removed icon.ico
Binary file not shown.
220 changes: 72 additions & 148 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,179 +1,103 @@
package main

import (
"net"
"strings"
"golang.org/x/sys/windows/svc"
//"golang.org/x/sys/windows/svc/debug"
"gopkg.in/natefinch/lumberjack.v2"
"log"
"os"
"path/filepath"
"time"
)

import (
"github.com/lxn/walk"
. "github.com/lxn/walk/declarative"
)

const LOCALHOST = "127.0.0.1"

type SDMainWindow struct {
*walk.MainWindow
ifaces *walk.ComboBox
btn *walk.PushButton
text *walk.TextEdit

type ServContext struct {
dnsSvcStop SvrStopFunc
}

func (w *SDMainWindow) onWindowLoad() {
// Attach MainWindow Closing Event Handler.
handle := w.Closing().Attach(w.onCloseWindow)
// svc.Handler 인터페이스 구현
func (srv *ServContext) Execute(args []string, req <-chan svc.ChangeRequest, stat chan<- svc.Status) (svcSpecificEC bool, exitCode uint32) {
stat <- svc.Status{State: svc.StartPending}

// startup DNS service
stopFunc, err := RunDNS(53, func(err error) {
// DNS server error
// 실제 서비스 내용
stopChan := make(chan bool, 1)
srv.runBody()

// Detach closing event handler.
// If DNS server error has occured, doesn't ask to user before closing.
w.Closing().Detach(handle)
stat <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop | svc.AcceptShutdown}

// display error message
walk.MsgBox(w, "SecureDNS 오류", "DNS 오류: "+err.Error(), walk.MsgBoxOK)
LOOP:
for {
// 서비스 변경 요청에 대해 핸들링
switch r := <-req; r.Cmd {
case svc.Stop, svc.Shutdown:
stopChan <- true
break LOOP

// and close main window.
w.Close()
})
case svc.Interrogate:
stat <- r.CurrentStatus
time.Sleep(100 * time.Millisecond)
stat <- r.CurrentStatus

if err != nil {
walk.MsgBox(w, "SecureDNS 오류", "DNS 오류: "+err.Error(), walk.MsgBoxOK)
} else {
w.dnsSvcStop = stopFunc
//case svc.Pause:
//case svc.Continue:
}
}

// refresh dns info
w.updateDNSInfo()
}

func (w *SDMainWindow) updateDNSInfo() {
var sb strings.Builder
sb.WriteString("Cloudflare DNS Over HTTPS가 작동중입니다.\r\n")
sb.WriteString("안전한 DNS 사용을 위하여 네트워크 설정에서\r\n")
sb.WriteString("시스템의 DNS 주소를 127.0.0.1로 변경하여 적용하십시오.\r\n")
stat <- svc.Status{State: svc.StopPending}

w.text.SetText(sb.String())
}

func (w *SDMainWindow) toggleSecDNS() {

}
// Stop DNS server
log.Println("Shutting down...")

func (w *SDMainWindow) onMenuAbout() {
var sb strings.Builder
sb.WriteString("SecureDNS 0.1\r\n\r\n")
sb.WriteString("Cloudflare DNS Over HTTPS를 사용한 안전한 DNS 연결 제공\r\n")
sb.WriteString("https://github.com/Regentag/SecureDNS")
de := srv.dnsSvcStop()
if de != nil {
WriteErrorLogMsg("DNS service shutdown error: ", de)
} else {
log.Println("DNS service stopped.")
}

walk.MsgBox(w, "정보...", sb.String(), walk.MsgBoxOK)
log.Println("SecDNS was stopped.")
return
}

func (w *SDMainWindow) onCloseWindow(canceled *bool, reason walk.CloseReason) {
var sb strings.Builder
sb.WriteString("Cloudflare DNS Over HTTPS가 작동중입니다.\r\n")
sb.WriteString("SecureDNS를 종료한 후 인터넷을 사용하시려면\r\n")
sb.WriteString("네트워크 설정에서 시스템의 DNS 주소를 본래의 주소로 되돌리십시오.\r\n")
sb.WriteString("\r\nSecureDNS를 종료할까요?")
func (srv *ServContext) runBody() {
// DNS 서버를 go routine으로 시작하고
// 서버 종료를 위한 함수를 얻어 저장한다.
stopFunc, err := RunDNS(53, func(err error) {
WriteErrorLogMsg("DNS service error: ", err)
})

yn := walk.MsgBox(w, "종료", sb.String(), walk.MsgBoxYesNo)
if yn != 6 { // not IDYES(6)
*canceled = true
if err != nil {
WriteErrorLogMsgF("Can't start DNS service. ", err)
} else {
if w.dnsSvcStop != nil {
w.dnsSvcStop()
}
srv.dnsSvcStop = stopFunc
log.Println("SecDNS service started.")
}
}

func getNetworkIfaces() []string {
ifaces, _ := net.Interfaces()
var sl []string

for _, iface := range ifaces {
if iface.Flags&net.FlagUp == 0 {
continue
}
if iface.Flags&net.FlagLoopback != 0 {
continue
}

sl = append(sl, iface.Name)
func logPath(filename string) string {
ex, err := os.Executable()
if err != nil {
ex = "." // current working directory
}

return sl
exPath := filepath.Dir(ex)
return filepath.Join(exPath, filename)
}

func main() {
ifaces := getNetworkIfaces() // Network interfaces

mw := &SDMainWindow{dnsSvcStop: nil}

MainWindow{
AssignTo: &mw.MainWindow,
Title: "SecureDNS 0.1",
Size: Size{Width: 500, Height: 500},
Layout: VBox{MarginsZero: true},
Font: Font{
Family: "Segoe UI",
PointSize: 13,
},
MenuItems: []MenuItem{
Menu{
Text: "파일(&F)",
Items: []MenuItem{
Action{
Text: "Exit",
OnTriggered: func() { mw.Close() },
},
},
},
Menu{
Text: "도움말(&H)",
Items: []MenuItem{
Action{
Text: "SecureDNS 정보...",
OnTriggered: mw.onMenuAbout,
},
},
},
},
Children: []Widget{
Composite{
Layout: HBox{MarginsZero: false, SpacingZero: false},
Children: []Widget{
Label{Text: "네트워크 연결: "},
ComboBox{
AssignTo: &mw.ifaces,
Model: ifaces,
OnCurrentIndexChanged: mw.updateDNSInfo,
},
HSpacer{},
/*
PushButton{
Text: "DNS 보안 켜기",
AssignTo: &mw.btn,
Enabled: false,
OnClicked: mw.toggleSecDNS,
},
*/
},
},

TextEdit{
AssignTo: &mw.text,
HScroll: true,
VScroll: true,
ReadOnly: true,
Text: "Ready.",
Background: SolidColorBrush{Color: walk.RGB(255, 255, 240)},
},
},
}.Create()
mw.Starting().Attach(mw.onWindowLoad)
mw.ifaces.SetCurrentIndex(0)
mw.Run()
log.SetOutput(&lumberjack.Logger{
Filename: logPath("sec-dns.log"),
MaxSize: 10, // megabytes
MaxBackups: 1,
MaxAge: 28, //days
Compress: false, // disabled by default
})

log.Println("Initializing...")

err := svc.Run("SecDNS", &ServContext{})
//err = debug.Run("DummyService", &dummyService{}) //콘솔출력 디버깅시
if err != nil {
WriteErrorLogMsgF("Fatal service error: ", err)
panic(err)
}
}
16 changes: 16 additions & 0 deletions service_install.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@ECHO OFF
PUSHD "%~dp0"

echo This script should be run with administrator privileges.
echo Right click - run as administrator.
echo Press any key if you're running it as administrator.
pause

sc stop "SecureDNS"
sc delete "SecureDNS"
sc create "SecureDNS" binPath= "\"%CD%\SecureDNS.exe\"" start= "auto" DisplayName= "Secure DNS"
sc description "SecureDNS" "DNS proxy service for DOH (DNS over HTTPS) support."
sc start "SecureDNS"
pause

POPD
9 changes: 9 additions & 0 deletions service_remove.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@ECHO OFF
echo This script should be run with administrator privileges.
echo Right click - run as administrator.
echo Press any key if you're running it as administrator.
pause

sc stop "SecureDNS"
sc delete "SecureDNS"
pause
Loading

0 comments on commit 5fb5139

Please sign in to comment.