Skip to content

Commit

Permalink
Use /etc/hosts file to resolve listen address and list on all IPs listed
Browse files Browse the repository at this point in the history
Fixes #22
  • Loading branch information
rs committed Jan 2, 2020
1 parent 54243b6 commit 7dd6eb3
Show file tree
Hide file tree
Showing 27 changed files with 635 additions and 123 deletions.
6 changes: 2 additions & 4 deletions activate.go
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/nextdns/nextdns/config"
"github.com/nextdns/nextdns/host"
"github.com/nextdns/nextdns/hosts"
)

func activation(args []string) error {
Expand Down Expand Up @@ -42,10 +43,7 @@ func listenIP(listen string) (string, error) {
case "::":
return "::1", nil
}
addrs, err := net.LookupHost(host)
if err != nil {
return "", fmt.Errorf("activate: %s: %v", listen, err)
}
addrs := hosts.LookupHost(host)
if len(addrs) == 0 {
return "", fmt.Errorf("activate: %s: no address found", listen)
}
Expand Down
2 changes: 2 additions & 0 deletions host/dns_freebsd.go → host/dns_bsd.go
@@ -1,3 +1,5 @@
// +build freebsd openbsd netbsd dragonfly

package host

import (
Expand Down
2 changes: 1 addition & 1 deletion host/dns_other.go
@@ -1,4 +1,4 @@
// +build !darwin,!linux,!freebsd
// +build !darwin,!linux,!freebsd,!openbsd,!netbsd,!dragonfly

package host

Expand Down
2 changes: 1 addition & 1 deletion host/dns_resolvconf.go
@@ -1,4 +1,4 @@
// +build linux freebsd
// +build linux freebsd openbsd netbsd dragonfly

package host

Expand Down
2 changes: 2 additions & 0 deletions host/log_freebsd.go → host/log_bsd.go
@@ -1,3 +1,5 @@
// +build freebsd openbsd netbsd dragonfly

package host

import (
Expand Down
2 changes: 1 addition & 1 deletion host/log_other.go
@@ -1,4 +1,4 @@
// +build !linux,!freebsd,!darwin
// +build !darwin,!linux,!freebsd,!openbsd,!netbsd,!dragonfly

package host

Expand Down
7 changes: 5 additions & 2 deletions host/log_syslog.go
@@ -1,3 +1,5 @@
// +build !windows

package host

import (
Expand All @@ -18,11 +20,12 @@ func newSyslogLogger(name string) (Logger, error) {
}

func (l syslogLogger) Info(v ...interface{}) {
_ = l.syslog.Info(fmt.Sprint(v...))
// Use notice instead of info as many systems filter < notice level
_ = l.syslog.Notice(fmt.Sprint(v...))
}

func (l syslogLogger) Infof(format string, a ...interface{}) {
_ = l.syslog.Info(fmt.Sprintf(format, a...))
_ = l.syslog.Notice(fmt.Sprintf(format, a...))
}

func (l syslogLogger) Warning(v ...interface{}) {
Expand Down
25 changes: 12 additions & 13 deletions host/log_windows.go
@@ -1,6 +1,9 @@
package host

import (
"fmt"
"strings"

"golang.org/x/sys/windows/svc/debug"
"golang.org/x/sys/windows/svc/eventlog"
)
Expand All @@ -13,18 +16,18 @@ func newConsoleLogger(name string) Logger {
return windowsLogger{log: debug.New(name)}
}

func newServiceLogger(name string) (log.Logger, error) {
err = eventlog.InstallAsEventCreate(name, eventlog.Error|eventlog.Warning|eventlog.Info)
func newServiceLogger(name string) (Logger, error) {
err := eventlog.InstallAsEventCreate(name, eventlog.Error|eventlog.Warning|eventlog.Info)
if err != nil {
if !strings.Contains(err.Error(), "exists") {
return err
return nil, err
}
}
el, err := logentlog.Open(name)
el, err := eventlog.Open(name)
if err != nil {
return nil, err
}
return windowsLogger{log: el}
return windowsLogger{log: el}, nil
}

func (l windowsLogger) Info(v ...interface{}) {
Expand All @@ -36,21 +39,17 @@ func (l windowsLogger) Infof(format string, a ...interface{}) {
}

func (l windowsLogger) Warning(v ...interface{}) {
return l.log.Warning(2, fmt.Sprint(v...))
l.log.Warning(2, fmt.Sprint(v...))
}

func (l windowsLogger) Warningf(format string, a ...interface{}) {
return l.log.Warning(2, fmt.Sprintf(format, a...))
l.log.Warning(2, fmt.Sprintf(format, a...))
}

func (l windowsLogger) Error(v ...interface{}) {
return l.log.Error(3, fmt.Sprint(v...))
l.log.Error(3, fmt.Sprint(v...))
}

func (l windowsLogger) Errorf(format string, a ...interface{}) {
return l.log.Error(3, fmt.Sprintf(format, a...))
l.log.Error(3, fmt.Sprintf(format, a...))
}




4 changes: 2 additions & 2 deletions host/service/bsd/service.go
Expand Up @@ -94,8 +94,8 @@ name="{{.Name}}"
{{.Name}}_env="{{.RunModeEnv}}=1"
pidfile="/var/run/${name}.pid"
command="/usr/sbin/daemon"
daemon_args="-P ${pidfile} -r -t \"${name}: daemon\"{{if .WorkingDirectory}} -c {{.WorkingDirectory}}{{end}}"
command_args="${daemon_args} {{.Path}}{{range .Arguments}} {{.}}{{end}}"
daemon_args="-P ${pidfile} -r -t \"${name}: daemon\""
command_args="${daemon_args} {{.Executable}}{{range .Arguments}} {{.}}{{end}}"
run_rc_command "$1"
`
4 changes: 2 additions & 2 deletions host/service/run.go
Expand Up @@ -11,11 +11,11 @@ type Runner interface {
Stop() error
}

func Run(r Runner) error {
func Run(name string, r Runner) error {
if CurrentRunMode() == RunModeNone {
return runForeground(r)
}
return runService(r)
return runService(name, r)
}

func runForeground(r Runner) error {
Expand Down
2 changes: 1 addition & 1 deletion host/service/run_unix.go
Expand Up @@ -2,6 +2,6 @@

package service

func runService(r Runner) error {
func runService(name string, r Runner) error {
return runForeground(r)
}
10 changes: 5 additions & 5 deletions host/service/run_windows.go
Expand Up @@ -13,7 +13,7 @@ type windowService struct {
func (s windowService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (bool, uint32) {
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
changes <- svc.Status{State: svc.StartPending}
if err := s.Start(s.log); err != nil {
if err := s.Start(); err != nil {
s.lastErr = err
return true, 1
}
Expand All @@ -27,7 +27,7 @@ loop:
changes <- c.CurrentStatus
case svc.Stop, svc.Shutdown:
changes <- svc.Status{State: svc.StopPending}
if err := s.Stop(s.log); err != nil {
if err := s.Stop(); err != nil {
s.lastErr = err
return true, 2
}
Expand All @@ -38,12 +38,12 @@ loop:
return false, 0
}

func runService(r Runner) error {
func runService(name string, r Runner) error {
runner := svc.Run
if isDebug {
if interactive, _ := svc.IsAnInteractiveSession(); interactive {
runner = debug.Run
}
s := &windowService{r}
s := &windowService{Runner: r}
err := runner(name, s)
if s.lastErr != nil {
return s.lastErr
Expand Down
4 changes: 2 additions & 2 deletions host/service/service_windows.go
Expand Up @@ -5,8 +5,8 @@ import (
)

func CurrentRunMode() RunMode {
if interactive, err = svc.IsAnInteractiveSession(); interactive || err != nil {
return RunModeNode
if interactive, err := svc.IsAnInteractiveSession(); interactive || err != nil {
return RunModeNone
}
return RunModeService
}
2 changes: 1 addition & 1 deletion host/service/systemd/service.go
Expand Up @@ -27,7 +27,7 @@ func New(c service.Config) (Service, error) {
return Service{
Config: c,
ConfigFileStorer: service.ConfigFileStorer{File: "/etc/" + c.Name + ".conf"},
Path: "/etc/Service/system/" + c.Name + ".service",
Path: "/etc/systemd/system/" + c.Name + ".service",
}, nil
}

Expand Down
71 changes: 30 additions & 41 deletions host/service/windows/service.go
Expand Up @@ -27,7 +27,7 @@ func New(c service.Config) (Service, error) {
if err != nil {
return Service{}, err
}
confPath := filepath.Join(filepath.Dir(ep), c.Name+".conf"), nil
confPath := filepath.Join(filepath.Dir(ep), c.Name+".conf")
return Service{
Config: c,
ConfigFileStorer: service.ConfigFileStorer{File: confPath},
Expand All @@ -44,21 +44,21 @@ func (s Service) Install() error {
return err
}
defer m.Disconnect()
s, err := m.OpenService(s.Name)
srv, err := m.OpenService(s.Name)
if err == nil {
s.Close()
return ErrAlreadyInstalled
srv.Close()
return service.ErrAlreadyInstalled
}
s, err = m.CreateService(s.Name, ep, mgr.Config{
srv, err = m.CreateService(s.Name, ep, mgr.Config{
DisplayName: s.DisplayName,
Description: s.Description,
StartType: mgr.StartAutomatic,
}, s.Arguments...)
if err != nil {
return err
}
defer s.Close()
err = s.SetRecoveryActions([]mgr.RecoveryAction{
defer srv.Close()
err = srv.SetRecoveryActions([]mgr.RecoveryAction{
mgr.RecoveryAction{
Type: mgr.ServiceRestart,
Delay: 5 * time.Second,
Expand All @@ -77,55 +77,43 @@ func (s Service) Uninstall() error {
return err
}
defer m.Disconnect()
s, err := m.OpenService(s.Name)
srv, err := m.OpenService(s.Name)
if err != nil {
return ErrNoInstalled
return service.ErrNoInstalled
}
defer s.Close()
err = s.Delete()
defer srv.Close()
err = srv.Delete()
if err != nil {
return err
}
return nil
}

func (s Service) Status() (Status, error) {
func (s Service) Status() (service.Status, error) {
m, err := mgr.Connect()
if err != nil {
return StatusUnknown, err
return service.StatusUnknown, err
}
defer m.Disconnect()

s, err := m.OpenService(s.Name)
srv, err := m.OpenService(s.Name)
if err != nil {
if err.Error() == "The specified service does not exist as an installed service." {
return StatusNotInstalled, nil
return service.StatusNotInstalled, nil
}
return StatusUnknown, err
return service.StatusUnknown, err
}

status, err := s.Query()
status, err := srv.Query()
if err != nil {
return StatusUnknown, err
return service.StatusUnknown, err
}

switch status.State {
case svc.StartPending:
fallthrough
case svc.Running:
return StatusRunning, nil
case svc.PausePending:
fallthrough
case svc.Paused:
fallthrough
case svc.ContinuePending:
fallthrough
case svc.StopPending:
fallthrough
case svc.Stopped:
return StatusStopped, nil
case svc.StartPending, svc.Running, svc.PausePending, svc.Paused, svc.ContinuePending, svc.StopPending, svc.Stopped:
return service.StatusStopped, nil
default:
return StatusUnknown, fmt.Errorf("unknown status %v", status)
return service.StatusUnknown, fmt.Errorf("unknown status %v", status)
}
}

Expand All @@ -136,12 +124,12 @@ func (s Service) Start() error {
}
defer m.Disconnect()

svc, err := m.OpenService(ws.Name)
srv, err := m.OpenService(s.Name)
if err != nil {
return err
}
defer svc.Close()
return svc.Start()
defer srv.Close()
return srv.Start()
}

func (s Service) Stop() error {
Expand All @@ -150,12 +138,12 @@ func (s Service) Stop() error {
return err
}
defer m.Disconnect()
svc, err := m.OpenService(name)
srv, err := m.OpenService(s.Name)
if err != nil {
return fmt.Errorf("could not access service: %v", err)
}
defer svc.Close()
status, err := svc.Control(svc.Stop)
defer srv.Close()
status, err := srv.Control(svc.Stop)
if err != nil {
return fmt.Errorf("could not send control=%d: %v", svc.Stop, err)
}
Expand All @@ -165,12 +153,13 @@ func (s Service) Stop() error {
return fmt.Errorf("timeout waiting for service to go to state=%d", svc.Stopped)
}
time.Sleep(300 * time.Millisecond)
status, err = svc.Query()
status, err = srv.Query()
if err != nil {
return fmt.Errorf("could not retrieve service status: %v", err)
}
}
return nil}
return nil
}

func (s Service) Restart() error {
if err := s.Stop(); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion host/service_bsd.go
@@ -1,4 +1,4 @@
// +build freebsd,openbsd,netbsd,dragonfly
// +build freebsd openbsd netbsd dragonfly

package host

Expand Down
2 changes: 1 addition & 1 deletion host/service_windows.go
@@ -1,4 +1,4 @@
package service
package host

import (
"github.com/nextdns/nextdns/host/service"
Expand Down

0 comments on commit 7dd6eb3

Please sign in to comment.