Pull request:* all: remove github.com/joomcode/errorx dependency

Merge in DNS/adguard-home from 2240-removing-errorx-dependency to master

Squashed commit of the following:

commit 5bbe0567356f06e3b9ee5b3dc38d357b472cacb1
Merge: a6040850d 02d16a0b4
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Nov 5 14:32:22 2020 +0300

    Merge branch 'master' into 2240-removing-errorx-dependency

commit a6040850da3cefb131208097477b0956e80063fb
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Nov 5 14:23:36 2020 +0300

    * dhcpd: convert some abbreviations to lowercase.

commit d05bd51b994906b0ff52c5a8e779bd1f512f4bb7
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Nov 5 12:47:20 2020 +0300

    * agherr: last final fixes

commit 164bca55035ff44e50b0abb33e129a0d24ffe87c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Nov 3 19:11:10 2020 +0300

    * all: final fixes again

commit a0ac26f409c0b28a176cf2861d52c2f471b59484
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Nov 3 18:51:39 2020 +0300

    * all: final fixes

commit 6147b02d402b513323b07e85856b348884f3a088
Merge: 9fd3af1a3 62cc334f4
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 18:26:03 2020 +0300

    Merge branch 'master' into 2240-removing-errorx-dependency

commit 9fd3af1a39a3189b5c41315a8ad1568ae5cb4fc9
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 18:23:08 2020 +0300

    * all: remove useless helper

commit 7cd9aeae639762b28b25f354d69c5cf74f670211
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 17:19:26 2020 +0300

    * agherr: improved code tidiness

commit a74a49236e9aaace070646dac710de9201105262
Merge: dc9dedbf2 df34ee5c0
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 16:54:29 2020 +0300

    Merge branch 'master' into 2240-removing-errorx-dependency

commit dc9dedbf205756e3adaa3bc776d349bf3d8c69a5
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 16:40:08 2020 +0300

    * agherr: improve and cover by tests

commit fd6bfe9e282156cc60e006cb7cd46cce4d3a07a8
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 14:06:27 2020 +0300

    * all: improve code quality

commit ea00c2f8c5060e9611f9a80cfd0e4a039526d0c4
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 13:03:57 2020 +0300

    * all: fix linter style warnings

commit 8e75e1a681a7218c2b4c69adfa2b7e1e2966f9ac
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 12:29:26 2020 +0300

    * all: remove github.com/joomcode/errorx dependency

    Closes #2240.
This commit is contained in:
Eugene Burkov 2020-11-05 15:20:57 +03:00
parent 02d16a0b40
commit 2baa33fb1f
32 changed files with 342 additions and 250 deletions

1
go.mod
View File

@ -12,7 +12,6 @@ require (
github.com/gobuffalo/packr v1.30.1 github.com/gobuffalo/packr v1.30.1
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714
github.com/insomniacslk/dhcp v0.0.0-20200621044212-d74cd86ad5b8 github.com/insomniacslk/dhcp v0.0.0-20200621044212-d74cd86ad5b8
github.com/joomcode/errorx v1.0.3
github.com/kardianos/service v1.1.0 github.com/kardianos/service v1.1.0
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7 github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065 github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065

2
go.sum
View File

@ -136,8 +136,6 @@ github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/joomcode/errorx v1.0.1 h1:CalpDWz14ZHd68fIqluJasJosAewpz2TFaJALrUxjrk= github.com/joomcode/errorx v1.0.1 h1:CalpDWz14ZHd68fIqluJasJosAewpz2TFaJALrUxjrk=
github.com/joomcode/errorx v1.0.1/go.mod h1:kgco15ekB6cs+4Xjzo7SPeXzx38PbJzBwbnu9qfVNHQ= github.com/joomcode/errorx v1.0.1/go.mod h1:kgco15ekB6cs+4Xjzo7SPeXzx38PbJzBwbnu9qfVNHQ=
github.com/joomcode/errorx v1.0.3 h1:3e1mi0u7/HTPNdg6d6DYyKGBhA5l9XpsfuVE29NxnWw=
github.com/joomcode/errorx v1.0.3/go.mod h1:eQzdtdlNyN7etw6YCS4W4+lu442waxZYw5yvz0ULrRo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/kardianos/service v1.1.0 h1:QV2SiEeWK42P0aEmGcsAgjApw/lRxkwopvT+Gu6t1/0= github.com/kardianos/service v1.1.0 h1:QV2SiEeWK42P0aEmGcsAgjApw/lRxkwopvT+Gu6t1/0=

59
internal/agherr/agherr.go Normal file
View File

@ -0,0 +1,59 @@
// Package agherr contains the extended error type, and the function for
// wrapping several errors.
package agherr
import (
"fmt"
"strings"
)
// manyError is an error containing several wrapped errors. It is created to be
// a simpler version of the API provided by github.com/joomcode/errorx.
type manyError struct {
message string
underlying []error
}
// Many wraps several errors and returns a single error.
func Many(message string, underlying ...error) error {
err := &manyError{
message: message,
underlying: underlying,
}
return err
}
// Error implements the error interface for *manyError.
func (e *manyError) Error() string {
switch len(e.underlying) {
case 0:
return e.message
case 1:
return fmt.Sprintf("%s: %s", e.message, e.underlying[0])
default:
b := &strings.Builder{}
// Ignore errors, since strings.(*Buffer).Write never returns
// errors.
_, _ = fmt.Fprintf(b, "%s: %s (hidden: %s", e.message, e.underlying[0], e.underlying[1])
for _, u := range e.underlying[2:] {
// See comment above.
_, _ = fmt.Fprintf(b, ", %s", u)
}
// See comment above.
_, _ = b.WriteString(")")
return b.String()
}
}
// Unwrap implements the hidden errors.wrapper interface for *manyError.
func (e *manyError) Unwrap() error {
if len(e.underlying) == 0 {
return nil
}
return e.underlying[0]
}

View File

@ -0,0 +1,73 @@
package agherr
import (
"errors"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestError_Error(t *testing.T) {
testCases := []struct {
name string
want string
err error
}{{
name: "simple",
want: "a",
err: Many("a"),
}, {
name: "wrapping",
want: "a: b",
err: Many("a", errors.New("b")),
}, {
name: "wrapping several",
want: "a: b (hidden: c, d)",
err: Many("a", errors.New("b"), errors.New("c"), errors.New("d")),
}, {
name: "wrapping wrapper",
want: "a: b: c (hidden: d)",
err: Many("a", Many("b", errors.New("c"), errors.New("d"))),
}}
for _, tc := range testCases {
assert.Equal(t, tc.want, tc.err.Error(), tc.name)
}
}
func TestError_Unwrap(t *testing.T) {
const (
errSimple = iota
errWrapped
errNil
)
errs := []error{
errSimple: errors.New("a"),
errWrapped: fmt.Errorf("%w", errors.New("nested")),
errNil: nil,
}
testCases := []struct {
name string
want error
wrapped error
}{{
name: "simple",
want: errs[errSimple],
wrapped: Many("a", errs[errSimple]),
}, {
name: "nested",
want: errs[errWrapped],
wrapped: Many("b", errs[errWrapped]),
}, {
name: "nil passed",
want: errs[errNil],
wrapped: Many("c", errs[errNil]),
}, {
name: "nil not passed",
want: nil,
wrapped: Many("d"),
}}
for _, tc := range testCases {
assert.Equal(t, tc.want, errors.Unwrap(tc.wrapped), tc.name)
}
}

View File

@ -23,7 +23,7 @@ import (
func CheckIfOtherDHCPServersPresentV4(ifaceName string) (bool, error) { func CheckIfOtherDHCPServersPresentV4(ifaceName string) (bool, error) {
iface, err := net.InterfaceByName(ifaceName) iface, err := net.InterfaceByName(ifaceName)
if err != nil { if err != nil {
return false, wrapErrPrint(err, "Couldn't find interface by name %s", ifaceName) return false, fmt.Errorf("couldn't find interface by name %s: %w", ifaceName, err)
} }
// get ipv4 address of an interface // get ipv4 address of an interface
@ -44,7 +44,7 @@ func CheckIfOtherDHCPServersPresentV4(ifaceName string) (bool, error) {
req, err := dhcpv4.NewDiscovery(iface.HardwareAddr) req, err := dhcpv4.NewDiscovery(iface.HardwareAddr)
if err != nil { if err != nil {
return false, fmt.Errorf("dhcpv4.NewDiscovery: %s", err) return false, fmt.Errorf("dhcpv4.NewDiscovery: %w", err)
} }
req.Options.Update(dhcpv4.OptClientIdentifier(iface.HardwareAddr)) req.Options.Update(dhcpv4.OptClientIdentifier(iface.HardwareAddr))
req.Options.Update(dhcpv4.OptHostName(hostname)) req.Options.Update(dhcpv4.OptHostName(hostname))
@ -52,24 +52,24 @@ func CheckIfOtherDHCPServersPresentV4(ifaceName string) (bool, error) {
// resolve 0.0.0.0:68 // resolve 0.0.0.0:68
udpAddr, err := net.ResolveUDPAddr("udp4", src) udpAddr, err := net.ResolveUDPAddr("udp4", src)
if err != nil { if err != nil {
return false, wrapErrPrint(err, "Couldn't resolve UDP address %s", src) return false, fmt.Errorf("couldn't resolve UDP address %s: %w", src, err)
} }
if !udpAddr.IP.To4().Equal(srcIP) { if !udpAddr.IP.To4().Equal(srcIP) {
return false, wrapErrPrint(err, "Resolved UDP address is not %s", src) return false, fmt.Errorf("resolved UDP address is not %s: %w", src, err)
} }
// resolve 255.255.255.255:67 // resolve 255.255.255.255:67
dstAddr, err := net.ResolveUDPAddr("udp4", dst) dstAddr, err := net.ResolveUDPAddr("udp4", dst)
if err != nil { if err != nil {
return false, wrapErrPrint(err, "Couldn't resolve UDP address %s", dst) return false, fmt.Errorf("couldn't resolve UDP address %s: %w", dst, err)
} }
// bind to 0.0.0.0:68 // bind to 0.0.0.0:68
log.Tracef("Listening to udp4 %+v", udpAddr) log.Tracef("Listening to udp4 %+v", udpAddr)
c, err := nclient4.NewRawUDPConn(ifaceName, 68) c, err := nclient4.NewRawUDPConn(ifaceName, 68)
if err != nil { if err != nil {
return false, wrapErrPrint(err, "Couldn't listen on :68") return false, fmt.Errorf("couldn't listen on :68: %w", err)
} }
if c != nil { if c != nil {
defer c.Close() defer c.Close()
@ -78,7 +78,7 @@ func CheckIfOtherDHCPServersPresentV4(ifaceName string) (bool, error) {
// send to 255.255.255.255:67 // send to 255.255.255.255:67
_, err = c.WriteTo(req.ToBytes(), dstAddr) _, err = c.WriteTo(req.ToBytes(), dstAddr)
if err != nil { if err != nil {
return false, wrapErrPrint(err, "Couldn't send a packet to %s", dst) return false, fmt.Errorf("couldn't send a packet to %s: %w", dst, err)
} }
for { for {
@ -94,7 +94,7 @@ func CheckIfOtherDHCPServersPresentV4(ifaceName string) (bool, error) {
return false, nil return false, nil
} }
if err != nil { if err != nil {
return false, wrapErrPrint(err, "Couldn't receive packet") return false, fmt.Errorf("couldn't receive packet: %w", err)
} }
log.Tracef("Received packet (%v bytes)", n) log.Tracef("Received packet (%v bytes)", n)
@ -127,12 +127,12 @@ func CheckIfOtherDHCPServersPresentV4(ifaceName string) (bool, error) {
func CheckIfOtherDHCPServersPresentV6(ifaceName string) (bool, error) { func CheckIfOtherDHCPServersPresentV6(ifaceName string) (bool, error) {
iface, err := net.InterfaceByName(ifaceName) iface, err := net.InterfaceByName(ifaceName)
if err != nil { if err != nil {
return false, fmt.Errorf("DHCPv6: net.InterfaceByName: %s: %s", ifaceName, err) return false, fmt.Errorf("dhcpv6: net.InterfaceByName: %s: %w", ifaceName, err)
} }
ifaceIPNet := getIfaceIPv6(*iface) ifaceIPNet := getIfaceIPv6(*iface)
if len(ifaceIPNet) == 0 { if len(ifaceIPNet) == 0 {
return false, fmt.Errorf("DHCPv6: couldn't find IPv6 address of interface %s %+v", ifaceName, iface) return false, fmt.Errorf("dhcpv6: couldn't find IPv6 address of interface %s %+v", ifaceName, iface)
} }
srcIP := ifaceIPNet[0] srcIP := ifaceIPNet[0]
@ -141,27 +141,27 @@ func CheckIfOtherDHCPServersPresentV6(ifaceName string) (bool, error) {
req, err := dhcpv6.NewSolicit(iface.HardwareAddr) req, err := dhcpv6.NewSolicit(iface.HardwareAddr)
if err != nil { if err != nil {
return false, fmt.Errorf("DHCPv6: dhcpv6.NewSolicit: %s", err) return false, fmt.Errorf("dhcpv6: dhcpv6.NewSolicit: %w", err)
} }
udpAddr, err := net.ResolveUDPAddr("udp6", src) udpAddr, err := net.ResolveUDPAddr("udp6", src)
if err != nil { if err != nil {
return false, wrapErrPrint(err, "DHCPv6: Couldn't resolve UDP address %s", src) return false, fmt.Errorf("dhcpv6: Couldn't resolve UDP address %s: %w", src, err)
} }
if !udpAddr.IP.To16().Equal(srcIP) { if !udpAddr.IP.To16().Equal(srcIP) {
return false, wrapErrPrint(err, "DHCPv6: Resolved UDP address is not %s", src) return false, fmt.Errorf("dhcpv6: Resolved UDP address is not %s: %w", src, err)
} }
dstAddr, err := net.ResolveUDPAddr("udp6", dst) dstAddr, err := net.ResolveUDPAddr("udp6", dst)
if err != nil { if err != nil {
return false, fmt.Errorf("DHCPv6: Couldn't resolve UDP address %s: %s", dst, err) return false, fmt.Errorf("dhcpv6: Couldn't resolve UDP address %s: %w", dst, err)
} }
log.Debug("DHCPv6: Listening to udp6 %+v", udpAddr) log.Debug("DHCPv6: Listening to udp6 %+v", udpAddr)
c, err := nclient6.NewIPv6UDPConn(ifaceName, dhcpv6.DefaultClientPort) c, err := nclient6.NewIPv6UDPConn(ifaceName, dhcpv6.DefaultClientPort)
if err != nil { if err != nil {
return false, fmt.Errorf("DHCPv6: Couldn't listen on :546: %s", err) return false, fmt.Errorf("dhcpv6: Couldn't listen on :546: %w", err)
} }
if c != nil { if c != nil {
defer c.Close() defer c.Close()
@ -169,7 +169,7 @@ func CheckIfOtherDHCPServersPresentV6(ifaceName string) (bool, error) {
_, err = c.WriteTo(req.ToBytes(), dstAddr) _, err = c.WriteTo(req.ToBytes(), dstAddr)
if err != nil { if err != nil {
return false, fmt.Errorf("DHCPv6: Couldn't send a packet to %s: %s", dst, err) return false, fmt.Errorf("dhcpv6: Couldn't send a packet to %s: %w", dst, err)
} }
for { for {
@ -182,7 +182,7 @@ func CheckIfOtherDHCPServersPresentV6(ifaceName string) (bool, error) {
return false, nil return false, nil
} }
if err != nil { if err != nil {
return false, wrapErrPrint(err, "Couldn't receive packet") return false, fmt.Errorf("couldn't receive packet: %w", err)
} }
log.Debug("DHCPv6: Received packet (%v bytes)", n) log.Debug("DHCPv6: Received packet (%v bytes)", n)

View File

@ -4,9 +4,6 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"net" "net"
"github.com/AdguardTeam/golibs/log"
"github.com/joomcode/errorx"
) )
func isTimeout(err error) bool { func isTimeout(err error) bool {
@ -37,17 +34,6 @@ func getIfaceIPv4(iface net.Interface) []net.IP {
return res return res
} }
func wrapErrPrint(err error, message string, args ...interface{}) error {
var errx error
if err == nil {
errx = fmt.Errorf(message, args...)
} else {
errx = errorx.Decorate(err, message, args...)
}
log.Println(errx.Error())
return errx
}
func parseIPv4(text string) (net.IP, error) { func parseIPv4(text string) (net.IP, error) {
result := net.ParseIP(text) result := net.ParseIP(text)
if result == nil { if result == nil {

View File

@ -163,7 +163,7 @@ func (ra *raCtx) Init() error {
return nil return nil
} }
log.Debug("DHCPv6 RA: source IP address: %s DNS IP address: %s", log.Debug("dhcpv6 ra: source IP address: %s DNS IP address: %s",
ra.ipAddr, ra.dnsIPAddr) ra.ipAddr, ra.dnsIPAddr)
params := icmpv6RA{ params := icmpv6RA{
@ -183,7 +183,7 @@ func (ra *raCtx) Init() error {
ipAndScope := ra.ipAddr.String() + "%" + ra.ifaceName ipAndScope := ra.ipAddr.String() + "%" + ra.ifaceName
ra.conn, err = icmp.ListenPacket("ip6:ipv6-icmp", ipAndScope) ra.conn, err = icmp.ListenPacket("ip6:ipv6-icmp", ipAndScope)
if err != nil { if err != nil {
return fmt.Errorf("DHCPv6 RA: icmp.ListenPacket: %s", err) return fmt.Errorf("dhcpv6 ra: icmp.ListenPacket: %w", err)
} }
success := false success := false
defer func() { defer func() {
@ -195,11 +195,11 @@ func (ra *raCtx) Init() error {
con6 := ra.conn.IPv6PacketConn() con6 := ra.conn.IPv6PacketConn()
if err := con6.SetHopLimit(255); err != nil { if err := con6.SetHopLimit(255); err != nil {
return fmt.Errorf("DHCPv6 RA: SetHopLimit: %s", err) return fmt.Errorf("dhcpv6 ra: SetHopLimit: %w", err)
} }
if err := con6.SetMulticastHopLimit(255); err != nil { if err := con6.SetMulticastHopLimit(255); err != nil {
return fmt.Errorf("DHCPv6 RA: SetMulticastHopLimit: %s", err) return fmt.Errorf("dhcpv6 ra: SetMulticastHopLimit: %w", err)
} }
msg := &ipv6.ControlMessage{ msg := &ipv6.ControlMessage{
@ -212,15 +212,15 @@ func (ra *raCtx) Init() error {
} }
go func() { go func() {
log.Debug("DHCPv6 RA: starting to send periodic RouterAdvertisement packets") log.Debug("dhcpv6 ra: starting to send periodic RouterAdvertisement packets")
for ra.stop.Load() == 0 { for ra.stop.Load() == 0 {
_, err = con6.WriteTo(data, msg, addr) _, err = con6.WriteTo(data, msg, addr)
if err != nil { if err != nil {
log.Error("DHCPv6 RA: WriteTo: %s", err) log.Error("dhcpv6 ra: WriteTo: %s", err)
} }
time.Sleep(ra.packetSendPeriod) time.Sleep(ra.packetSendPeriod)
} }
log.Debug("DHCPv6 RA: loop exit") log.Debug("dhcpv6 ra: loop exit")
}() }()
success = true success = true
@ -229,7 +229,7 @@ func (ra *raCtx) Init() error {
// Close - close module // Close - close module
func (ra *raCtx) Close() { func (ra *raCtx) Close() {
log.Debug("DHCPv6 RA: closing") log.Debug("dhcpv6 ra: closing")
ra.stop.Store(1) ra.stop.Store(1)

View File

@ -55,7 +55,7 @@ func (s *v4Server) ResetLeases(leases []*Lease) {
if l.Expiry.Unix() != leaseExpireStatic && if l.Expiry.Unix() != leaseExpireStatic &&
!ip4InRange(s.conf.ipStart, s.conf.ipEnd, l.IP) { !ip4InRange(s.conf.ipStart, s.conf.ipEnd, l.IP) {
log.Debug("DHCPv4: skipping a lease with IP %v: not within current IP range", l.IP) log.Debug("dhcpv4: skipping a lease with IP %v: not within current IP range", l.IP)
continue continue
} }
@ -124,7 +124,7 @@ func (s *v4Server) blacklistLease(lease *Lease) {
// Remove (swap) lease by index // Remove (swap) lease by index
func (s *v4Server) leaseRemoveSwapByIndex(i int) { func (s *v4Server) leaseRemoveSwapByIndex(i int) {
s.ipAddrs[s.leases[i].IP[3]] = 0 s.ipAddrs[s.leases[i].IP[3]] = 0
log.Debug("DHCPv4: removed lease %s", s.leases[i].HWAddr) log.Debug("dhcpv4: removed lease %s", s.leases[i].HWAddr)
n := len(s.leases) n := len(s.leases)
if i != n-1 { if i != n-1 {
@ -168,7 +168,7 @@ func (s *v4Server) rmDynamicLease(lease Lease) error {
func (s *v4Server) addLease(l *Lease) { func (s *v4Server) addLease(l *Lease) {
s.leases = append(s.leases, l) s.leases = append(s.leases, l)
s.ipAddrs[l.IP[3]] = 1 s.ipAddrs[l.IP[3]] = 1
log.Debug("DHCPv4: added lease %s <-> %s", l.IP, l.HWAddr) log.Debug("dhcpv4: added lease %s <-> %s", l.IP, l.HWAddr)
} }
// Remove a lease with the same properties // Remove a lease with the same properties
@ -178,8 +178,7 @@ func (s *v4Server) rmLease(lease Lease) error {
if !bytes.Equal(l.HWAddr, lease.HWAddr) || if !bytes.Equal(l.HWAddr, lease.HWAddr) ||
l.Hostname != lease.Hostname { l.Hostname != lease.Hostname {
return fmt.Errorf("lease not found")
return fmt.Errorf("Lease not found")
} }
s.leaseRemoveSwapByIndex(i) s.leaseRemoveSwapByIndex(i)
@ -238,7 +237,6 @@ func (s *v4Server) RemoveStaticLease(l Lease) error {
// Send ICMP to the specified machine // Send ICMP to the specified machine
// Return TRUE if it doesn't reply, which probably means that the IP is available // Return TRUE if it doesn't reply, which probably means that the IP is available
func (s *v4Server) addrAvailable(target net.IP) bool { func (s *v4Server) addrAvailable(target net.IP) bool {
if s.conf.ICMPTimeout == 0 { if s.conf.ICMPTimeout == 0 {
return true return true
} }
@ -256,15 +254,15 @@ func (s *v4Server) addrAvailable(target net.IP) bool {
pinger.OnRecv = func(pkt *ping.Packet) { pinger.OnRecv = func(pkt *ping.Packet) {
reply = true reply = true
} }
log.Debug("DHCPv4: Sending ICMP Echo to %v", target) log.Debug("dhcpv4: Sending ICMP Echo to %v", target)
pinger.Run() pinger.Run()
if reply { if reply {
log.Info("DHCPv4: IP conflict: %v is already used by another device", target) log.Info("dhcpv4: IP conflict: %v is already used by another device", target)
return false return false
} }
log.Debug("DHCPv4: ICMP procedure is complete: %v", target) log.Debug("dhcpv4: ICMP procedure is complete: %v", target)
return true return true
} }
@ -349,7 +347,7 @@ func (s *v4Server) processDiscover(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) *Lea
for lease == nil { for lease == nil {
lease = s.reserveLease(mac) lease = s.reserveLease(mac)
if lease == nil { if lease == nil {
log.Debug("DHCPv4: No more IP addresses") log.Debug("dhcpv4: No more IP addresses")
if toStore { if toStore {
s.conf.notify(LeaseChangedDBStore) s.conf.notify(LeaseChangedDBStore)
} }
@ -372,7 +370,7 @@ func (s *v4Server) processDiscover(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) *Lea
reqIP := req.Options.Get(dhcpv4.OptionRequestedIPAddress) reqIP := req.Options.Get(dhcpv4.OptionRequestedIPAddress)
if len(reqIP) != 0 && if len(reqIP) != 0 &&
!bytes.Equal(reqIP, lease.IP) { !bytes.Equal(reqIP, lease.IP) {
log.Debug("DHCPv4: different RequestedIP: %v != %v", reqIP, lease.IP) log.Debug("dhcpv4: different RequestedIP: %v != %v", reqIP, lease.IP)
} }
} }
@ -407,7 +405,6 @@ func (o *optFQDN) ToBytes() []byte {
copy(b[i:], []byte(o.name)) copy(b[i:], []byte(o.name))
return b return b
} }
// Process Request request and return lease // Process Request request and return lease
@ -424,12 +421,12 @@ func (s *v4Server) processRequest(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) (*Lea
sid := req.Options.Get(dhcpv4.OptionServerIdentifier) sid := req.Options.Get(dhcpv4.OptionServerIdentifier)
if len(sid) != 0 && if len(sid) != 0 &&
!bytes.Equal(sid, s.conf.dnsIPAddrs[0]) { !bytes.Equal(sid, s.conf.dnsIPAddrs[0]) {
log.Debug("DHCPv4: Bad OptionServerIdentifier in Request message for %s", mac) log.Debug("dhcpv4: Bad OptionServerIdentifier in Request message for %s", mac)
return nil, false return nil, false
} }
if len(reqIP) != 4 { if len(reqIP) != 4 {
log.Debug("DHCPv4: Bad OptionRequestedIPAddress in Request message for %s", mac) log.Debug("dhcpv4: Bad OptionRequestedIPAddress in Request message for %s", mac)
return nil, false return nil, false
} }
@ -438,7 +435,7 @@ func (s *v4Server) processRequest(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) (*Lea
if bytes.Equal(l.HWAddr, mac) { if bytes.Equal(l.HWAddr, mac) {
if !bytes.Equal(l.IP, reqIP) { if !bytes.Equal(l.IP, reqIP) {
s.leasesLock.Unlock() s.leasesLock.Unlock()
log.Debug("DHCPv4: Mismatched OptionRequestedIPAddress in Request message for %s", mac) log.Debug("dhcpv4: Mismatched OptionRequestedIPAddress in Request message for %s", mac)
return nil, true return nil, true
} }
@ -449,7 +446,7 @@ func (s *v4Server) processRequest(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) (*Lea
s.leasesLock.Unlock() s.leasesLock.Unlock()
if lease == nil { if lease == nil {
log.Debug("DHCPv4: No lease for %s", mac) log.Debug("dhcpv4: No lease for %s", mac)
return nil, true return nil, true
} }
@ -476,7 +473,6 @@ func (s *v4Server) processRequest(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) (*Lea
// Return 0: error; reply with Nak // Return 0: error; reply with Nak
// Return -1: error; don't reply // Return -1: error; don't reply
func (s *v4Server) process(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) int { func (s *v4Server) process(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) int {
var lease *Lease var lease *Lease
resp.UpdateOption(dhcpv4.OptServerIdentifier(s.conf.dnsIPAddrs[0])) resp.UpdateOption(dhcpv4.OptServerIdentifier(s.conf.dnsIPAddrs[0]))
@ -519,7 +515,7 @@ func (s *v4Server) process(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) int {
// client(0.0.0.0:68) -> (Request:ClientMAC,Type=Request,ClientID,ReqIP||ClientIP,HostName,ServerID,ParamReqList) -> server(255.255.255.255:67) // client(0.0.0.0:68) -> (Request:ClientMAC,Type=Request,ClientID,ReqIP||ClientIP,HostName,ServerID,ParamReqList) -> server(255.255.255.255:67)
// client(255.255.255.255:68) <- (Reply:YourIP,ClientMAC,Type=ACK,ServerID,SubnetMask,LeaseTime) <- server(<IP>:67) // client(255.255.255.255:68) <- (Reply:YourIP,ClientMAC,Type=ACK,ServerID,SubnetMask,LeaseTime) <- server(<IP>:67)
func (s *v4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4.DHCPv4) { func (s *v4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4.DHCPv4) {
log.Debug("DHCPv4: received message: %s", req.Summary()) log.Debug("dhcpv4: received message: %s", req.Summary())
switch req.MessageType() { switch req.MessageType() {
case dhcpv4.MessageTypeDiscover, case dhcpv4.MessageTypeDiscover,
@ -527,18 +523,18 @@ func (s *v4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4
// //
default: default:
log.Debug("DHCPv4: unsupported message type %d", req.MessageType()) log.Debug("dhcpv4: unsupported message type %d", req.MessageType())
return return
} }
resp, err := dhcpv4.NewReplyFromRequest(req) resp, err := dhcpv4.NewReplyFromRequest(req)
if err != nil { if err != nil {
log.Debug("DHCPv4: dhcpv4.New: %s", err) log.Debug("dhcpv4: dhcpv4.New: %s", err)
return return
} }
if len(req.ClientHWAddr) != 6 { if len(req.ClientHWAddr) != 6 {
log.Debug("DHCPv4: Invalid ClientHWAddr") log.Debug("dhcpv4: Invalid ClientHWAddr")
return return
} }
@ -549,11 +545,11 @@ func (s *v4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4
resp.Options.Update(dhcpv4.OptMessageType(dhcpv4.MessageTypeNak)) resp.Options.Update(dhcpv4.OptMessageType(dhcpv4.MessageTypeNak))
} }
log.Debug("DHCPv4: sending: %s", resp.Summary()) log.Debug("dhcpv4: sending: %s", resp.Summary())
_, err = conn.WriteTo(resp.ToBytes(), peer) _, err = conn.WriteTo(resp.ToBytes(), peer)
if err != nil { if err != nil {
log.Error("DHCPv4: conn.Write to %s failed: %s", peer, err) log.Error("dhcpv4: conn.Write to %s failed: %s", peer, err)
return return
} }
} }
@ -566,13 +562,13 @@ func (s *v4Server) Start() error {
iface, err := net.InterfaceByName(s.conf.InterfaceName) iface, err := net.InterfaceByName(s.conf.InterfaceName)
if err != nil { if err != nil {
return fmt.Errorf("DHCPv4: Couldn't find interface by name %s: %s", s.conf.InterfaceName, err) return fmt.Errorf("dhcpv4: Couldn't find interface by name %s: %w", s.conf.InterfaceName, err)
} }
log.Debug("DHCPv4: starting...") log.Debug("dhcpv4: starting...")
s.conf.dnsIPAddrs = getIfaceIPv4(*iface) s.conf.dnsIPAddrs = getIfaceIPv4(*iface)
if len(s.conf.dnsIPAddrs) == 0 { if len(s.conf.dnsIPAddrs) == 0 {
log.Debug("DHCPv4: no IPv6 address for interface %s", iface.Name) log.Debug("dhcpv4: no IPv6 address for interface %s", iface.Name)
return nil return nil
} }
@ -585,11 +581,11 @@ func (s *v4Server) Start() error {
return err return err
} }
log.Info("DHCPv4: listening") log.Info("dhcpv4: listening")
go func() { go func() {
err = s.srv.Serve() err = s.srv.Serve()
log.Debug("DHCPv4: srv.Serve: %s", err) log.Debug("dhcpv4: srv.Serve: %s", err)
}() }()
return nil return nil
} }
@ -600,10 +596,10 @@ func (s *v4Server) Stop() {
return return
} }
log.Debug("DHCPv4: stopping") log.Debug("dhcpv4: stopping")
err := s.srv.Close() err := s.srv.Close()
if err != nil { if err != nil {
log.Error("DHCPv4: srv.Close: %s", err) log.Error("dhcpv4: srv.Close: %s", err)
} }
// now s.srv.Serve() will return // now s.srv.Serve() will return
s.srv = nil s.srv = nil
@ -621,31 +617,31 @@ func v4Create(conf V4ServerConf) (DHCPServer, error) {
var err error var err error
s.conf.routerIP, err = parseIPv4(s.conf.GatewayIP) s.conf.routerIP, err = parseIPv4(s.conf.GatewayIP)
if err != nil { if err != nil {
return s, fmt.Errorf("DHCPv4: %s", err) return s, fmt.Errorf("dhcpv4: %w", err)
} }
subnet, err := parseIPv4(s.conf.SubnetMask) subnet, err := parseIPv4(s.conf.SubnetMask)
if err != nil || !isValidSubnetMask(subnet) { if err != nil || !isValidSubnetMask(subnet) {
return s, fmt.Errorf("DHCPv4: invalid subnet mask: %s", s.conf.SubnetMask) return s, fmt.Errorf("dhcpv4: invalid subnet mask: %s", s.conf.SubnetMask)
} }
s.conf.subnetMask = make([]byte, 4) s.conf.subnetMask = make([]byte, 4)
copy(s.conf.subnetMask, subnet) copy(s.conf.subnetMask, subnet)
s.conf.ipStart, err = parseIPv4(conf.RangeStart) s.conf.ipStart, err = parseIPv4(conf.RangeStart)
if s.conf.ipStart == nil { if s.conf.ipStart == nil {
return s, fmt.Errorf("DHCPv4: %s", err) return s, fmt.Errorf("dhcpv4: %w", err)
} }
if s.conf.ipStart[0] == 0 { if s.conf.ipStart[0] == 0 {
return s, fmt.Errorf("DHCPv4: invalid range start IP") return s, fmt.Errorf("dhcpv4: invalid range start IP")
} }
s.conf.ipEnd, err = parseIPv4(conf.RangeEnd) s.conf.ipEnd, err = parseIPv4(conf.RangeEnd)
if s.conf.ipEnd == nil { if s.conf.ipEnd == nil {
return s, fmt.Errorf("DHCPv4: %s", err) return s, fmt.Errorf("dhcpv4: %w", err)
} }
if !net.IP.Equal(s.conf.ipStart[:3], s.conf.ipEnd[:3]) || if !net.IP.Equal(s.conf.ipStart[:3], s.conf.ipEnd[:3]) ||
s.conf.ipStart[3] > s.conf.ipEnd[3] { s.conf.ipStart[3] > s.conf.ipEnd[3] {
return s, fmt.Errorf("DHCPv4: range end IP should match range start IP") return s, fmt.Errorf("dhcpv4: range end IP should match range start IP")
} }
if conf.LeaseDuration == 0 { if conf.LeaseDuration == 0 {
@ -658,7 +654,7 @@ func v4Create(conf V4ServerConf) (DHCPServer, error) {
for _, o := range conf.Options { for _, o := range conf.Options {
code, val := parseOptionString(o) code, val := parseOptionString(o)
if code == 0 { if code == 0 {
log.Debug("DHCPv4: bad option string: %s", o) log.Debug("dhcpv4: bad option string: %s", o)
continue continue
} }

View File

@ -73,12 +73,10 @@ func (s *v6Server) GetLeases(flags int) []Lease {
var result []Lease var result []Lease
s.leasesLock.Lock() s.leasesLock.Lock()
for _, lease := range s.leases { for _, lease := range s.leases {
if lease.Expiry.Unix() == leaseExpireStatic { if lease.Expiry.Unix() == leaseExpireStatic {
if (flags & LeasesStatic) != 0 { if (flags & LeasesStatic) != 0 {
result = append(result, *lease) result = append(result, *lease)
} }
} else { } else {
if (flags & LeasesDynamic) != 0 { if (flags & LeasesDynamic) != 0 {
result = append(result, *lease) result = append(result, *lease)
@ -215,8 +213,7 @@ func (s *v6Server) rmLease(lease Lease) error {
if !bytes.Equal(l.HWAddr, lease.HWAddr) || if !bytes.Equal(l.HWAddr, lease.HWAddr) ||
l.Hostname != lease.Hostname { l.Hostname != lease.Hostname {
return fmt.Errorf("lease not found")
return fmt.Errorf("Lease not found")
} }
s.leaseRemoveSwapByIndex(i) s.leaseRemoveSwapByIndex(i)
@ -303,7 +300,7 @@ func (s *v6Server) commitDynamicLease(l *Lease) {
// Check Client ID // Check Client ID
func (s *v6Server) checkCID(msg *dhcpv6.Message) error { func (s *v6Server) checkCID(msg *dhcpv6.Message) error {
if msg.Options.ClientID() == nil { if msg.Options.ClientID() == nil {
return fmt.Errorf("DHCPv6: no ClientID option in request") return fmt.Errorf("dhcpv6: no ClientID option in request")
} }
return nil return nil
} }
@ -318,7 +315,7 @@ func (s *v6Server) checkSID(msg *dhcpv6.Message) error {
dhcpv6.MessageTypeRebind: dhcpv6.MessageTypeRebind:
if sid != nil { if sid != nil {
return fmt.Errorf("DHCPv6: drop packet: ServerID option in message %s", msg.Type().String()) return fmt.Errorf("dhcpv6: drop packet: ServerID option in message %s", msg.Type().String())
} }
case dhcpv6.MessageTypeRequest, case dhcpv6.MessageTypeRequest,
@ -327,10 +324,10 @@ func (s *v6Server) checkSID(msg *dhcpv6.Message) error {
dhcpv6.MessageTypeDecline: dhcpv6.MessageTypeDecline:
if sid == nil { if sid == nil {
return fmt.Errorf("DHCPv6: drop packet: no ServerID option in message %s", msg.Type().String()) return fmt.Errorf("dhcpv6: drop packet: no ServerID option in message %s", msg.Type().String())
} }
if !sid.Equal(s.sid) { if !sid.Equal(s.sid) {
return fmt.Errorf("DHCPv6: drop packet: mismatched ServerID option in message %s: %s", return fmt.Errorf("dhcpv6: drop packet: mismatched ServerID option in message %s: %s",
msg.Type().String(), sid.String()) msg.Type().String(), sid.String())
} }
} }
@ -589,7 +586,7 @@ func (s *v6Server) Start() error {
iface, err := net.InterfaceByName(s.conf.InterfaceName) iface, err := net.InterfaceByName(s.conf.InterfaceName)
if err != nil { if err != nil {
return wrapErrPrint(err, "Couldn't find interface by name %s", s.conf.InterfaceName) return fmt.Errorf("couldn't find interface by name %s: %w", s.conf.InterfaceName, err)
} }
s.conf.dnsIPAddrs = getIfaceIPv6(*iface) s.conf.dnsIPAddrs = getIfaceIPv6(*iface)
@ -612,7 +609,7 @@ func (s *v6Server) Start() error {
log.Debug("DHCPv6: starting...") log.Debug("DHCPv6: starting...")
if len(iface.HardwareAddr) != 6 { if len(iface.HardwareAddr) != 6 {
return fmt.Errorf("DHCPv6: invalid MAC %s", iface.HardwareAddr) return fmt.Errorf("dhcpv6: invalid MAC %s", iface.HardwareAddr)
} }
s.sid = dhcpv6.Duid{ s.sid = dhcpv6.Duid{
Type: dhcpv6.DUID_LLT, Type: dhcpv6.DUID_LLT,
@ -667,7 +664,7 @@ func v6Create(conf V6ServerConf) (DHCPServer, error) {
s.conf.ipStart = net.ParseIP(conf.RangeStart) s.conf.ipStart = net.ParseIP(conf.RangeStart)
if s.conf.ipStart == nil || s.conf.ipStart.To16() == nil { if s.conf.ipStart == nil || s.conf.ipStart.To16() == nil {
return s, fmt.Errorf("DHCPv6: invalid range-start IP: %s", conf.RangeStart) return s, fmt.Errorf("dhcpv6: invalid range-start IP: %s", conf.RangeStart)
} }
if conf.LeaseDuration == 0 { if conf.LeaseDuration == 0 {

View File

@ -22,12 +22,12 @@ func main() {
res, err := filter.CheckHost(host) res, err := filter.CheckHost(host)
if err != nil { if err != nil {
// temporary failure // temporary failure
log.Fatalf("Failed to check host '%s': %s", host, err) log.Fatalf("Failed to check host %q: %s", host, err)
} }
if res.IsFiltered { if res.IsFiltered {
log.Printf("Host %s is filtered, reason - '%s', matched rule: '%s'", host, res.Reason, res.Rule) log.Printf("Host %s is filtered, reason - %q, matched rule: %q", host, res.Reason, res.Rule)
} else { } else {
log.Printf("Host %s is not filtered, reason - '%s'", host, res.Reason) log.Printf("Host %s is not filtered, reason - %q", host, res.Reason)
} }
} }
``` ```
@ -59,12 +59,12 @@ func main() {
res, err := filter.CheckHost(host) res, err := filter.CheckHost(host)
if err != nil { if err != nil {
// temporary failure // temporary failure
log.Fatalf("Failed to check host '%s': %s", host, err) log.Fatalf("Failed to check host %q: %s", host, err)
} }
if res.IsFiltered { if res.IsFiltered {
log.Printf("Host %s is filtered, reason - '%s', matched rule: '%s'", host, res.Reason, res.Rule) log.Printf("Host %s is filtered, reason - %q, matched rule: %q", host, res.Reason, res.Rule)
} else { } else {
log.Printf("Host %s is not filtered, reason - '%s'", host, res.Reason) log.Printf("Host %s is not filtered, reason - %q", host, res.Reason)
} }
} }
``` ```

View File

@ -501,19 +501,17 @@ func createFilteringEngine(filters []Filter) (*filterlist.RuleStorage, *urlfilte
RulesText: string(f.Data), RulesText: string(f.Data),
IgnoreCosmetic: true, IgnoreCosmetic: true,
} }
} else if !fileExists(f.FilePath) { } else if !fileExists(f.FilePath) {
list = &filterlist.StringRuleList{ list = &filterlist.StringRuleList{
ID: int(f.ID), ID: int(f.ID),
IgnoreCosmetic: true, IgnoreCosmetic: true,
} }
} else if runtime.GOOS == "windows" { } else if runtime.GOOS == "windows" {
// On Windows we don't pass a file to urlfilter because // On Windows we don't pass a file to urlfilter because
// it's difficult to update this file while it's being used. // it's difficult to update this file while it's being used.
data, err := ioutil.ReadFile(f.FilePath) data, err := ioutil.ReadFile(f.FilePath)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("ioutil.ReadFile(): %s: %s", f.FilePath, err) return nil, nil, fmt.Errorf("ioutil.ReadFile(): %s: %w", f.FilePath, err)
} }
list = &filterlist.StringRuleList{ list = &filterlist.StringRuleList{
ID: int(f.ID), ID: int(f.ID),
@ -525,7 +523,7 @@ func createFilteringEngine(filters []Filter) (*filterlist.RuleStorage, *urlfilte
var err error var err error
list, err = filterlist.NewFileRuleList(int(f.ID), f.FilePath, true) list, err = filterlist.NewFileRuleList(int(f.ID), f.FilePath, true)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("filterlist.NewFileRuleList(): %s: %s", f.FilePath, err) return nil, nil, fmt.Errorf("filterlist.NewFileRuleList(): %s: %w", f.FilePath, err)
} }
} }
listArray = append(listArray, list) listArray = append(listArray, list)
@ -533,7 +531,7 @@ func createFilteringEngine(filters []Filter) (*filterlist.RuleStorage, *urlfilte
rulesStorage, err := filterlist.NewRuleStorage(listArray) rulesStorage, err := filterlist.NewRuleStorage(listArray)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("filterlist.NewRuleStorage(): %s", err) return nil, nil, fmt.Errorf("filterlist.NewRuleStorage(): %w", err)
} }
filteringEngine := urlfilter.NewDNSEngine(rulesStorage) filteringEngine := urlfilter.NewDNSEngine(rulesStorage)
return rulesStorage, filteringEngine, nil return rulesStorage, filteringEngine, nil
@ -590,7 +588,7 @@ func (d *Dnsfilter) matchHost(host string, qtype uint16, setts RequestFilteringS
rule = rr.HostRulesV6[0] rule = rr.HostRulesV6[0]
} }
log.Debug("Filtering: found whitelist rule for host '%s': '%s' list_id: %d", log.Debug("Filtering: found whitelist rule for host %q: %q list_id: %d",
host, rule.Text(), rule.GetFilterListID()) host, rule.Text(), rule.GetFilterListID())
res := makeResult(rule, NotFilteredWhiteList) res := makeResult(rule, NotFilteredWhiteList)
return res, nil return res, nil
@ -607,7 +605,7 @@ func (d *Dnsfilter) matchHost(host string, qtype uint16, setts RequestFilteringS
} }
if rr.NetworkRule != nil { if rr.NetworkRule != nil {
log.Debug("Filtering: found rule for host '%s': '%s' list_id: %d", log.Debug("Filtering: found rule for host %q: %q list_id: %d",
host, rr.NetworkRule.Text(), rr.NetworkRule.GetFilterListID()) host, rr.NetworkRule.Text(), rr.NetworkRule.GetFilterListID())
reason := FilteredBlackList reason := FilteredBlackList
if rr.NetworkRule.Whitelist { if rr.NetworkRule.Whitelist {
@ -619,7 +617,7 @@ func (d *Dnsfilter) matchHost(host string, qtype uint16, setts RequestFilteringS
if qtype == dns.TypeA && rr.HostRulesV4 != nil { if qtype == dns.TypeA && rr.HostRulesV4 != nil {
rule := rr.HostRulesV4[0] // note that we process only 1 matched rule rule := rr.HostRulesV4[0] // note that we process only 1 matched rule
log.Debug("Filtering: found rule for host '%s': '%s' list_id: %d", log.Debug("Filtering: found rule for host %q: %q list_id: %d",
host, rule.Text(), rule.GetFilterListID()) host, rule.Text(), rule.GetFilterListID())
res := makeResult(rule, FilteredBlackList) res := makeResult(rule, FilteredBlackList)
res.IP = rule.IP.To4() res.IP = rule.IP.To4()
@ -628,7 +626,7 @@ func (d *Dnsfilter) matchHost(host string, qtype uint16, setts RequestFilteringS
if qtype == dns.TypeAAAA && rr.HostRulesV6 != nil { if qtype == dns.TypeAAAA && rr.HostRulesV6 != nil {
rule := rr.HostRulesV6[0] // note that we process only 1 matched rule rule := rr.HostRulesV6[0] // note that we process only 1 matched rule
log.Debug("Filtering: found rule for host '%s': '%s' list_id: %d", log.Debug("Filtering: found rule for host %q: %q list_id: %d",
host, rule.Text(), rule.GetFilterListID()) host, rule.Text(), rule.GetFilterListID())
res := makeResult(rule, FilteredBlackList) res := makeResult(rule, FilteredBlackList)
res.IP = rule.IP res.IP = rule.IP
@ -644,7 +642,7 @@ func (d *Dnsfilter) matchHost(host string, qtype uint16, setts RequestFilteringS
} else if rr.HostRulesV6 != nil { } else if rr.HostRulesV6 != nil {
rule = rr.HostRulesV6[0] rule = rr.HostRulesV6[0]
} }
log.Debug("Filtering: found rule for host '%s': '%s' list_id: %d", log.Debug("Filtering: found rule for host %q: %q list_id: %d",
host, rule.Text(), rule.GetFilterListID()) host, rule.Text(), rule.GetFilterListID())
res := makeResult(rule, FilteredBlackList) res := makeResult(rule, FilteredBlackList)
res.IP = net.IP{} res.IP = net.IP{}
@ -673,7 +671,6 @@ func InitModule() {
// New creates properly initialized DNS Filter that is ready to be used // New creates properly initialized DNS Filter that is ready to be used
func New(c *Config, blockFilters []Filter) *Dnsfilter { func New(c *Config, blockFilters []Filter) *Dnsfilter {
if c != nil { if c != nil {
cacheConf := cache.Config{ cacheConf := cache.Config{
EnableLRU: true, EnableLRU: true,
@ -713,7 +710,7 @@ func New(c *Config, blockFilters []Filter) *Dnsfilter {
bsvcs := []string{} bsvcs := []string{}
for _, s := range d.BlockedServices { for _, s := range d.BlockedServices {
if !BlockedSvcKnown(s) { if !BlockedSvcKnown(s) {
log.Debug("skipping unknown blocked-service '%s'", s) log.Debug("skipping unknown blocked-service %q", s)
continue continue
} }
bsvcs = append(bsvcs, s) bsvcs = append(bsvcs, s)

View File

@ -51,7 +51,7 @@ func (a *accessCtx) Init(allowedClients, disallowedClients, blockedHosts []strin
listArray = append(listArray, list) listArray = append(listArray, list)
rulesStorage, err := filterlist.NewRuleStorage(listArray) rulesStorage, err := filterlist.NewRuleStorage(listArray)
if err != nil { if err != nil {
return fmt.Errorf("filterlist.NewRuleStorage(): %s", err) return fmt.Errorf("filterlist.NewRuleStorage(): %w", err)
} }
a.blockedHostsEngine = urlfilter.NewDNSEngine(rulesStorage) a.blockedHostsEngine = urlfilter.NewDNSEngine(rulesStorage)

View File

@ -15,7 +15,6 @@ import (
"github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/dnsproxy/upstream" "github.com/AdguardTeam/dnsproxy/upstream"
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
"github.com/joomcode/errorx"
) )
// FilteringConfig represents the DNS filtering configuration of AdGuard Home // FilteringConfig represents the DNS filtering configuration of AdGuard Home
@ -252,14 +251,14 @@ func (s *Server) prepareUpstreamSettings() error {
upstreams = filterOutComments(upstreams) upstreams = filterOutComments(upstreams)
upstreamConfig, err := proxy.ParseUpstreamsConfig(upstreams, s.conf.BootstrapDNS, DefaultTimeout) upstreamConfig, err := proxy.ParseUpstreamsConfig(upstreams, s.conf.BootstrapDNS, DefaultTimeout)
if err != nil { if err != nil {
return fmt.Errorf("DNS: proxy.ParseUpstreamsConfig: %s", err) return fmt.Errorf("dns: proxy.ParseUpstreamsConfig: %w", err)
} }
if len(upstreamConfig.Upstreams) == 0 { if len(upstreamConfig.Upstreams) == 0 {
log.Info("Warning: no default upstream servers specified, using %v", defaultDNS) log.Info("Warning: no default upstream servers specified, using %v", defaultDNS)
uc, err := proxy.ParseUpstreamsConfig(defaultDNS, s.conf.BootstrapDNS, DefaultTimeout) uc, err := proxy.ParseUpstreamsConfig(defaultDNS, s.conf.BootstrapDNS, DefaultTimeout)
if err != nil { if err != nil {
return fmt.Errorf("DNS: failed to parse default upstreams: %v", err) return fmt.Errorf("dns: failed to parse default upstreams: %v", err)
} }
upstreamConfig.Upstreams = uc.Upstreams upstreamConfig.Upstreams = uc.Upstreams
} }
@ -300,13 +299,13 @@ func (s *Server) prepareTLS(proxyConfig *proxy.Config) error {
var err error var err error
s.conf.cert, err = tls.X509KeyPair(s.conf.CertificateChainData, s.conf.PrivateKeyData) s.conf.cert, err = tls.X509KeyPair(s.conf.CertificateChainData, s.conf.PrivateKeyData)
if err != nil { if err != nil {
return errorx.Decorate(err, "Failed to parse TLS keypair") return fmt.Errorf("failed to parse TLS keypair: %w", err)
} }
if s.conf.StrictSNICheck { if s.conf.StrictSNICheck {
x, err := x509.ParseCertificate(s.conf.cert.Certificate[0]) x, err := x509.ParseCertificate(s.conf.cert.Certificate[0])
if err != nil { if err != nil {
return errorx.Decorate(err, "x509.ParseCertificate(): %s", err) return fmt.Errorf("x509.ParseCertificate(): %w", err)
} }
if len(x.DNSNames) != 0 { if len(x.DNSNames) != 0 {
s.conf.dnsNames = x.DNSNames s.conf.dnsNames = x.DNSNames

View File

@ -15,7 +15,6 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/stats" "github.com/AdguardTeam/AdGuardHome/internal/stats"
"github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
"github.com/joomcode/errorx"
"github.com/miekg/dns" "github.com/miekg/dns"
) )
@ -182,7 +181,7 @@ func (s *Server) Prepare(config *ServerConfig) error {
s.conf.BlockingIPAddrv4 = net.ParseIP(s.conf.BlockingIPv4) s.conf.BlockingIPAddrv4 = net.ParseIP(s.conf.BlockingIPv4)
s.conf.BlockingIPAddrv6 = net.ParseIP(s.conf.BlockingIPv6) s.conf.BlockingIPAddrv6 = net.ParseIP(s.conf.BlockingIPv6)
if s.conf.BlockingIPAddrv4 == nil || s.conf.BlockingIPAddrv6 == nil { if s.conf.BlockingIPAddrv4 == nil || s.conf.BlockingIPAddrv6 == nil {
return fmt.Errorf("DNS: invalid custom blocking IP address specified") return fmt.Errorf("dns: invalid custom blocking IP address specified")
} }
} }
if s.conf.MaxGoroutines == 0 { if s.conf.MaxGoroutines == 0 {
@ -250,7 +249,7 @@ func (s *Server) stopInternal() error {
if s.dnsProxy != nil { if s.dnsProxy != nil {
err := s.dnsProxy.Stop() err := s.dnsProxy.Stop()
if err != nil { if err != nil {
return errorx.Decorate(err, "could not stop the DNS server properly") return fmt.Errorf("could not stop the DNS server properly: %w", err)
} }
} }
@ -273,7 +272,7 @@ func (s *Server) Reconfigure(config *ServerConfig) error {
log.Print("Start reconfiguring the server") log.Print("Start reconfiguring the server")
err := s.stopInternal() err := s.stopInternal()
if err != nil { if err != nil {
return errorx.Decorate(err, "could not reconfigure the server") return fmt.Errorf("could not reconfigure the server: %w", err)
} }
// It seems that net.Listener.Close() doesn't close file descriptors right away. // It seems that net.Listener.Close() doesn't close file descriptors right away.
@ -282,12 +281,12 @@ func (s *Server) Reconfigure(config *ServerConfig) error {
err = s.Prepare(config) err = s.Prepare(config)
if err != nil { if err != nil {
return errorx.Decorate(err, "could not reconfigure the server") return fmt.Errorf("could not reconfigure the server: %w", err)
} }
err = s.startInternal() err = s.startInternal()
if err != nil { if err != nil {
return errorx.Decorate(err, "could not reconfigure the server") return fmt.Errorf("could not reconfigure the server: %w", err)
} }
return nil return nil

View File

@ -17,7 +17,7 @@ import (
func httpError(r *http.Request, w http.ResponseWriter, code int, format string, args ...interface{}) { func httpError(r *http.Request, w http.ResponseWriter, code int, format string, args ...interface{}) {
text := fmt.Sprintf(format, args...) text := fmt.Sprintf(format, args...)
log.Info("DNS: %s %s: %s", r.Method, r.URL, text) log.Info("dns: %s %s: %s", r.Method, r.URL, text)
http.Error(w, text, code) http.Error(w, text, code)
} }
@ -102,7 +102,7 @@ func checkBootstrap(addr string) error {
} }
_, err := upstream.NewResolver(addr, 0) _, err := upstream.NewResolver(addr, 0)
if err != nil { if err != nil {
return fmt.Errorf("invalid bootstrap server address: %s", err) return fmt.Errorf("invalid bootstrap server address: %w", err)
} }
return nil return nil
} }
@ -322,7 +322,7 @@ func separateUpstream(upstream string) (string, bool, error) {
// split domains and upstream string // split domains and upstream string
domainsAndUpstream := strings.Split(strings.TrimPrefix(upstream, "[/"), "/]") domainsAndUpstream := strings.Split(strings.TrimPrefix(upstream, "[/"), "/]")
if len(domainsAndUpstream) != 2 { if len(domainsAndUpstream) != 2 {
return "", defaultUpstream, fmt.Errorf("wrong DNS upstream per domain specification: %s", upstream) return "", defaultUpstream, fmt.Errorf("wrong dns upstream per domain specification: %s", upstream)
} }
// split domains list and validate each one // split domains list and validate each one
@ -357,7 +357,7 @@ func checkPlainDNS(upstream string) error {
_, err = strconv.ParseInt(port, 0, 64) _, err = strconv.ParseInt(port, 0, 64)
if err != nil { if err != nil {
return fmt.Errorf("%s is not a valid port: %s", port, err) return fmt.Errorf("%s is not a valid port: %w", port, err)
} }
return nil return nil
@ -405,7 +405,7 @@ func checkDNS(input string, bootstrap []string) error {
// separate upstream from domains list // separate upstream from domains list
input, defaultUpstream, err := separateUpstream(input) input, defaultUpstream, err := separateUpstream(input)
if err != nil { if err != nil {
return fmt.Errorf("wrong upstream format: %s", err) return fmt.Errorf("wrong upstream format: %w", err)
} }
// No need to check this DNS server // No need to check this DNS server
@ -414,17 +414,17 @@ func checkDNS(input string, bootstrap []string) error {
} }
if _, err := validateUpstream(input); err != nil { if _, err := validateUpstream(input); err != nil {
return fmt.Errorf("wrong upstream format: %s", err) return fmt.Errorf("wrong upstream format: %w", err)
} }
if len(bootstrap) == 0 { if len(bootstrap) == 0 {
bootstrap = defaultBootstrap bootstrap = defaultBootstrap
} }
log.Debug("Checking if DNS %s works...", input) log.Debug("checking if dns %s works...", input)
u, err := upstream.AddressToUpstream(input, upstream.Options{Bootstrap: bootstrap, Timeout: DefaultTimeout}) u, err := upstream.AddressToUpstream(input, upstream.Options{Bootstrap: bootstrap, Timeout: DefaultTimeout})
if err != nil { if err != nil {
return fmt.Errorf("failed to choose upstream for %s: %s", input, err) return fmt.Errorf("failed to choose upstream for %s: %w", input, err)
} }
req := dns.Msg{} req := dns.Msg{}
@ -435,18 +435,18 @@ func checkDNS(input string, bootstrap []string) error {
} }
reply, err := u.Exchange(&req) reply, err := u.Exchange(&req)
if err != nil { if err != nil {
return fmt.Errorf("couldn't communicate with DNS server %s: %s", input, err) return fmt.Errorf("couldn't communicate with dns server %s: %w", input, err)
} }
if len(reply.Answer) != 1 { if len(reply.Answer) != 1 {
return fmt.Errorf("DNS server %s returned wrong answer", input) return fmt.Errorf("dns server %s returned wrong answer", input)
} }
if t, ok := reply.Answer[0].(*dns.A); ok { if t, ok := reply.Answer[0].(*dns.A); ok {
if !net.IPv4(8, 8, 8, 8).Equal(t.A) { if !net.IPv4(8, 8, 8, 8).Equal(t.A) {
return fmt.Errorf("DNS server %s returned wrong answer: %v", input, t.A) return fmt.Errorf("dns server %s returned wrong answer: %v", input, t.A)
} }
} }
log.Debug("DNS %s works OK", input) log.Debug("dns %s works OK", input)
return nil return nil
} }
@ -462,7 +462,7 @@ func (s *Server) handleDOH(w http.ResponseWriter, r *http.Request) {
} }
if !s.IsRunning() { if !s.IsRunning() {
httpError(r, w, http.StatusInternalServerError, "DNS server is not running") httpError(r, w, http.StatusInternalServerError, "dns server is not running")
return return
} }

View File

@ -1,12 +1,13 @@
package dnsforward package dnsforward
import ( import (
"fmt"
"strings" "strings"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter" "github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
"github.com/joomcode/errorx"
"github.com/miekg/dns" "github.com/miekg/dns"
) )
@ -49,10 +50,9 @@ func (s *Server) filterDNSRequest(ctx *dnsContext) (*dnsfilter.Result, error) {
res, err := s.dnsFilter.CheckHost(host, d.Req.Question[0].Qtype, ctx.setts) res, err := s.dnsFilter.CheckHost(host, d.Req.Question[0].Qtype, ctx.setts)
if err != nil { if err != nil {
// Return immediately if there's an error // Return immediately if there's an error
return nil, errorx.Decorate(err, "dnsfilter failed to check host '%s'", host) return nil, fmt.Errorf("dnsfilter failed to check host %q: %w", host, err)
} else if res.IsFiltered { } else if res.IsFiltered {
log.Tracef("Host %s is filtered, reason - '%s', matched rule: '%s'", host, res.Reason, res.Rule) log.Tracef("Host %s is filtered, reason - %q, matched rule: %q", host, res.Reason, res.Rule)
d.Res = s.genDNSFilterMessage(d, &res) d.Res = s.genDNSFilterMessage(d, &res)
} else if res.Reason == dnsfilter.ReasonRewrite && len(res.CanonName) != 0 && len(res.IPList) == 0 { } else if res.Reason == dnsfilter.ReasonRewrite && len(res.CanonName) != 0 && len(res.IPList) == 0 {
@ -136,7 +136,6 @@ func (s *Server) filterDNSResponse(ctx *dnsContext) (*dnsfilter.Result, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} else if res.IsFiltered { } else if res.IsFiltered {
d.Res = s.genDNSFilterMessage(d, &res) d.Res = s.genDNSFilterMessage(d, &res)
log.Debug("DNSFwd: Matched %s by response: %s", d.Req.Question[0].Name, host) log.Debug("DNSFwd: Matched %s by response: %s", d.Req.Question[0].Name, host)

View File

@ -31,13 +31,13 @@ func (c *ipsetCtx) init(ipsetConfig []string) {
it = strings.TrimSpace(it) it = strings.TrimSpace(it)
hostsAndNames := strings.Split(it, "/") hostsAndNames := strings.Split(it, "/")
if len(hostsAndNames) != 2 { if len(hostsAndNames) != 2 {
log.Debug("IPSET: invalid value '%s'", it) log.Debug("IPSET: invalid value %q", it)
continue continue
} }
ipsetNames := strings.Split(hostsAndNames[1], ",") ipsetNames := strings.Split(hostsAndNames[1], ",")
if len(ipsetNames) == 0 { if len(ipsetNames) == 0 {
log.Debug("IPSET: invalid value '%s'", it) log.Debug("IPSET: invalid value %q", it)
continue continue
} }
bad := false bad := false
@ -49,7 +49,7 @@ func (c *ipsetCtx) init(ipsetConfig []string) {
} }
} }
if bad { if bad {
log.Debug("IPSET: invalid value '%s'", it) log.Debug("IPSET: invalid value %q", it)
continue continue
} }
@ -58,7 +58,7 @@ func (c *ipsetCtx) init(ipsetConfig []string) {
host = strings.TrimSpace(host) host = strings.TrimSpace(host)
host = strings.ToLower(host) host = strings.ToLower(host)
if len(host) == 0 { if len(host) == 0 {
log.Debug("IPSET: invalid value '%s'", it) log.Debug("IPSET: invalid value %q", it)
continue continue
} }
c.ipsetList[host] = ipsetNames c.ipsetList[host] = ipsetNames
@ -131,7 +131,7 @@ func (c *ipsetCtx) process(ctx *dnsContext) int {
continue continue
} }
if code != 0 { if code != 0 {
log.Info("IPSET: ipset add: code:%d output:'%s'", code, out) log.Info("IPSET: ipset add: code:%d output:%q", code, out)
continue continue
} }
log.Debug("IPSET: added %s(%s) -> %s", host, ipStr, name) log.Debug("IPSET: added %s(%s) -> %s", host, ipStr, name)

View File

@ -46,7 +46,6 @@ func (s *Server) genDNSFilterMessage(d *proxy.DNSContext, result *dnsfilter.Resu
if s.conf.BlockingMode == "null_ip" { if s.conf.BlockingMode == "null_ip" {
// it means that we should return 0.0.0.0 or :: for any blocked request // it means that we should return 0.0.0.0 or :: for any blocked request
return s.makeResponseNullIP(m) return s.makeResponseNullIP(m)
} else if s.conf.BlockingMode == "custom_ip" { } else if s.conf.BlockingMode == "custom_ip" {
// means that we should return custom IP for any blocked request // means that we should return custom IP for any blocked request
@ -56,12 +55,10 @@ func (s *Server) genDNSFilterMessage(d *proxy.DNSContext, result *dnsfilter.Resu
case dns.TypeAAAA: case dns.TypeAAAA:
return s.genAAAARecord(m, s.conf.BlockingIPAddrv6) return s.genAAAARecord(m, s.conf.BlockingIPAddrv6)
} }
} else if s.conf.BlockingMode == "nxdomain" { } else if s.conf.BlockingMode == "nxdomain" {
// means that we should return NXDOMAIN for any blocked request // means that we should return NXDOMAIN for any blocked request
return s.genNXDomain(m) return s.genNXDomain(m)
} else if s.conf.BlockingMode == "refused" { } else if s.conf.BlockingMode == "refused" {
// means that we should return NXDOMAIN for any blocked request // means that we should return NXDOMAIN for any blocked request
@ -148,7 +145,6 @@ func (s *Server) makeResponseNullIP(req *dns.Msg) *dns.Msg {
} }
func (s *Server) genBlockedHost(request *dns.Msg, newAddr string, d *proxy.DNSContext) *dns.Msg { func (s *Server) genBlockedHost(request *dns.Msg, newAddr string, d *proxy.DNSContext) *dns.Msg {
ip := net.ParseIP(newAddr) ip := net.ParseIP(newAddr)
if ip != nil { if ip != nil {
return s.genResponseWithIP(request, ip) return s.genResponseWithIP(request, ip)
@ -168,7 +164,7 @@ func (s *Server) genBlockedHost(request *dns.Msg, newAddr string, d *proxy.DNSCo
err := s.dnsProxy.Resolve(newContext) err := s.dnsProxy.Resolve(newContext)
if err != nil { if err != nil {
log.Printf("Couldn't look up replacement host '%s': %s", newAddr, err) log.Printf("Couldn't look up replacement host %q: %s", newAddr, err)
return s.genServerFailure(request) return s.genServerFailure(request)
} }

View File

@ -17,8 +17,10 @@ import (
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
) )
const cookieTTL = 365 * 24 // in hours const (
const sessionCookieName = "agh_session" cookieTTL = 365 * 24 // in hours
sessionCookieName = "agh_session"
)
type session struct { type session struct {
userName string userName string
@ -78,7 +80,7 @@ func InitAuth(dbFilename string, users []User, sessionTTL uint32) *Auth {
a.sessions = make(map[string]*session) a.sessions = make(map[string]*session)
rand.Seed(time.Now().UTC().Unix()) rand.Seed(time.Now().UTC().Unix())
var err error var err error
a.db, err = bbolt.Open(dbFilename, 0644, nil) a.db, err = bbolt.Open(dbFilename, 0o644, nil)
if err != nil { if err != nil {
log.Error("Auth: open DB: %s: %s", dbFilename, err) log.Error("Auth: open DB: %s: %s", dbFilename, err)
if err.Error() == "invalid argument" { if err.Error() == "invalid argument" {
@ -318,7 +320,7 @@ func handleLogin(w http.ResponseWriter, r *http.Request) {
cookie := Context.auth.httpCookie(req) cookie := Context.auth.httpCookie(req)
if len(cookie) == 0 { if len(cookie) == 0 {
log.Info("Auth: invalid user name or password: name='%s'", req.Name) log.Info("Auth: invalid user name or password: name=%q", req.Name)
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
http.Error(w, "invalid user name or password", http.StatusBadRequest) http.Error(w, "invalid user name or password", http.StatusBadRequest)
return return
@ -372,7 +374,6 @@ func parseCookie(cookie string) string {
// nolint(gocyclo) // nolint(gocyclo)
func optionalAuth(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) { func optionalAuth(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/login.html" { if r.URL.Path == "/login.html" {
// redirect to dashboard if already authenticated // redirect to dashboard if already authenticated
authRequired := Context.auth != nil && Context.auth.AuthRequired() authRequired := Context.auth != nil && Context.auth.AuthRequired()
@ -424,7 +425,6 @@ func optionalAuth(handler func(http.ResponseWriter, *http.Request)) func(http.Re
if r.URL.Path == "/" || r.URL.Path == "/index.html" { if r.URL.Path == "/" || r.URL.Path == "/index.html" {
if glProcessRedirect(w, r) { if glProcessRedirect(w, r) {
log.Debug("Auth: redirected to login page by GL-Inet submodule") log.Debug("Auth: redirected to login page by GL-Inet submodule")
} else { } else {
w.Header().Set("Location", "/login.html") w.Header().Set("Location", "/login.html")
w.WriteHeader(http.StatusFound) w.WriteHeader(http.StatusFound)

View File

@ -126,7 +126,6 @@ func (clients *clientsContainer) Start() {
} }
go clients.periodicUpdate() go clients.periodicUpdate()
} }
} }
// Reload - reload auto-clients // Reload - reload auto-clients
@ -173,7 +172,7 @@ func (clients *clientsContainer) addFromConfig(objects []clientObject) {
for _, s := range cy.BlockedServices { for _, s := range cy.BlockedServices {
if !dnsfilter.BlockedSvcKnown(s) { if !dnsfilter.BlockedSvcKnown(s) {
log.Debug("Clients: skipping unknown blocked-service '%s'", s) log.Debug("Clients: skipping unknown blocked-service %q", s)
continue continue
} }
cli.BlockedServices = append(cli.BlockedServices, s) cli.BlockedServices = append(cli.BlockedServices, s)
@ -181,7 +180,7 @@ func (clients *clientsContainer) addFromConfig(objects []clientObject) {
for _, t := range cy.Tags { for _, t := range cy.Tags {
if !clients.tagKnown(t) { if !clients.tagKnown(t) {
log.Debug("Clients: skipping unknown tag '%s'", t) log.Debug("Clients: skipping unknown tag %q", t)
continue continue
} }
cli.Tags = append(cli.Tags, t) cli.Tags = append(cli.Tags, t)
@ -377,7 +376,7 @@ func (clients *clientsContainer) check(c *Client) error {
} }
if len(c.IDs) == 0 { if len(c.IDs) == 0 {
return fmt.Errorf("ID required") return fmt.Errorf("id required")
} }
for i, id := range c.IDs { for i, id := range c.IDs {
@ -409,7 +408,7 @@ func (clients *clientsContainer) check(c *Client) error {
err := dnsforward.ValidateUpstreams(c.Upstreams) err := dnsforward.ValidateUpstreams(c.Upstreams)
if err != nil { if err != nil {
return fmt.Errorf("invalid upstream servers: %s", err) return fmt.Errorf("invalid upstream servers: %w", err)
} }
return nil return nil
@ -448,7 +447,7 @@ func (clients *clientsContainer) Add(c Client) (bool, error) {
clients.idIndex[id] = &c clients.idIndex[id] = &c
} }
log.Debug("Clients: added '%s': ID:%v [%d]", c.Name, c.IDs, len(clients.list)) log.Debug("Clients: added %q: ID:%v [%d]", c.Name, c.IDs, len(clients.list))
return true, nil return true, nil
} }
@ -590,7 +589,7 @@ func (clients *clientsContainer) addHost(ip, host string, source clientSource) (
} }
clients.ipHost[ip] = ch clients.ipHost[ip] = ch
} }
log.Debug("Clients: added '%s' -> '%s' [%d]", ip, host, len(clients.ipHost)) log.Debug("Clients: added %q -> %q [%d]", ip, host, len(clients.ipHost))
return true, nil return true, nil
} }

View File

@ -71,6 +71,7 @@ type checkConfigReqEnt struct {
IP string `json:"ip"` IP string `json:"ip"`
Autofix bool `json:"autofix"` Autofix bool `json:"autofix"`
} }
type checkConfigReq struct { type checkConfigReq struct {
Web checkConfigReqEnt `json:"web"` Web checkConfigReqEnt `json:"web"`
DNS checkConfigReqEnt `json:"dns"` DNS checkConfigReqEnt `json:"dns"`
@ -81,11 +82,13 @@ type checkConfigRespEnt struct {
Status string `json:"status"` Status string `json:"status"`
CanAutofix bool `json:"can_autofix"` CanAutofix bool `json:"can_autofix"`
} }
type staticIPJSON struct { type staticIPJSON struct {
Static string `json:"static"` Static string `json:"static"`
IP string `json:"ip"` IP string `json:"ip"`
Error string `json:"error"` Error string `json:"error"`
} }
type checkConfigResp struct { type checkConfigResp struct {
Web checkConfigRespEnt `json:"web"` Web checkConfigRespEnt `json:"web"`
DNS checkConfigRespEnt `json:"dns"` DNS checkConfigRespEnt `json:"dns"`
@ -214,31 +217,33 @@ func checkDNSStubListener() bool {
return true return true
} }
const resolvedConfPath = "/etc/systemd/resolved.conf.d/adguardhome.conf" const (
const resolvedConfData = `[Resolve] resolvedConfPath = "/etc/systemd/resolved.conf.d/adguardhome.conf"
resolvedConfData = `[Resolve]
DNS=127.0.0.1 DNS=127.0.0.1
DNSStubListener=no DNSStubListener=no
` `
)
const resolvConfPath = "/etc/resolv.conf" const resolvConfPath = "/etc/resolv.conf"
// Deactivate DNSStubListener // Deactivate DNSStubListener
func disableDNSStubListener() error { func disableDNSStubListener() error {
dir := filepath.Dir(resolvedConfPath) dir := filepath.Dir(resolvedConfPath)
err := os.MkdirAll(dir, 0755) err := os.MkdirAll(dir, 0o755)
if err != nil { if err != nil {
return fmt.Errorf("os.MkdirAll: %s: %s", dir, err) return fmt.Errorf("os.MkdirAll: %s: %w", dir, err)
} }
err = ioutil.WriteFile(resolvedConfPath, []byte(resolvedConfData), 0644) err = ioutil.WriteFile(resolvedConfPath, []byte(resolvedConfData), 0o644)
if err != nil { if err != nil {
return fmt.Errorf("ioutil.WriteFile: %s: %s", resolvedConfPath, err) return fmt.Errorf("ioutil.WriteFile: %s: %w", resolvedConfPath, err)
} }
_ = os.Rename(resolvConfPath, resolvConfPath+".backup") _ = os.Rename(resolvConfPath, resolvConfPath+".backup")
err = os.Symlink("/run/systemd/resolve/resolv.conf", resolvConfPath) err = os.Symlink("/run/systemd/resolve/resolv.conf", resolvConfPath)
if err != nil { if err != nil {
_ = os.Remove(resolvedConfPath) // remove the file we've just created _ = os.Remove(resolvedConfPath) // remove the file we've just created
return fmt.Errorf("os.Symlink: %s: %s", resolvConfPath, err) return fmt.Errorf("os.Symlink: %s: %w", resolvConfPath, err)
} }
cmd := exec.Command("systemctl", "reload-or-restart", "systemd-resolved") cmd := exec.Command("systemctl", "reload-or-restart", "systemd-resolved")
@ -259,6 +264,7 @@ type applyConfigReqEnt struct {
IP string `json:"ip"` IP string `json:"ip"`
Port int `json:"port"` Port int `json:"port"`
} }
type applyConfigReq struct { type applyConfigReq struct {
Web applyConfigReqEnt `json:"web"` Web applyConfigReqEnt `json:"web"`
DNS applyConfigReqEnt `json:"dns"` DNS applyConfigReqEnt `json:"dns"`

View File

@ -12,7 +12,6 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/util" "github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
"github.com/joomcode/errorx"
) )
// Called by other modules when configuration is changed // Called by other modules when configuration is changed
@ -75,7 +74,7 @@ func initDNSServer() error {
err = Context.dnsServer.Prepare(&dnsConfig) err = Context.dnsServer.Prepare(&dnsConfig)
if err != nil { if err != nil {
closeDNSServer() closeDNSServer()
return fmt.Errorf("dnsServer.Prepare: %s", err) return fmt.Errorf("dnsServer.Prepare: %w", err)
} }
Context.rdns = InitRDNS(Context.dnsServer, &Context.clients) Context.rdns = InitRDNS(Context.dnsServer, &Context.clients)
@ -96,41 +95,41 @@ func isPublicIP(ip net.IP) bool {
if ip4 != nil { if ip4 != nil {
switch ip4[0] { switch ip4[0] {
case 0: case 0:
return false //software return false // software
case 10: case 10:
return false //private network return false // private network
case 127: case 127:
return false //loopback return false // loopback
case 169: case 169:
if ip4[1] == 254 { if ip4[1] == 254 {
return false //link-local return false // link-local
} }
case 172: case 172:
if ip4[1] >= 16 && ip4[1] <= 31 { if ip4[1] >= 16 && ip4[1] <= 31 {
return false //private network return false // private network
} }
case 192: case 192:
if (ip4[1] == 0 && ip4[2] == 0) || //private network if (ip4[1] == 0 && ip4[2] == 0) || // private network
(ip4[1] == 0 && ip4[2] == 2) || //documentation (ip4[1] == 0 && ip4[2] == 2) || // documentation
(ip4[1] == 88 && ip4[2] == 99) || //reserved (ip4[1] == 88 && ip4[2] == 99) || // reserved
(ip4[1] == 168) { //private network (ip4[1] == 168) { // private network
return false return false
} }
case 198: case 198:
if (ip4[1] == 18 || ip4[2] == 19) || //private network if (ip4[1] == 18 || ip4[2] == 19) || // private network
(ip4[1] == 51 || ip4[2] == 100) { //documentation (ip4[1] == 51 || ip4[2] == 100) { // documentation
return false return false
} }
case 203: case 203:
if ip4[1] == 0 && ip4[2] == 113 { //documentation if ip4[1] == 0 && ip4[2] == 113 { // documentation
return false return false
} }
case 224: case 224:
if ip4[1] == 0 && ip4[2] == 0 { //multicast if ip4[1] == 0 && ip4[2] == 0 { // multicast
return false return false
} }
case 255: case 255:
if ip4[1] == 255 && ip4[2] == 255 && ip4[3] == 255 { //subnet if ip4[1] == 255 && ip4[2] == 255 && ip4[3] == 255 { // subnet
return false return false
} }
} }
@ -313,7 +312,7 @@ func startDNSServer() error {
err := Context.dnsServer.Start() err := Context.dnsServer.Start()
if err != nil { if err != nil {
return errorx.Decorate(err, "Couldn't start forwarding DNS server") return fmt.Errorf("couldn't start forwarding DNS server: %w", err)
} }
Context.dnsFilter.Start() Context.dnsFilter.Start()
@ -340,7 +339,7 @@ func reconfigureDNSServer() error {
newconfig := generateServerConfig() newconfig := generateServerConfig()
err := Context.dnsServer.Reconfigure(&newconfig) err := Context.dnsServer.Reconfigure(&newconfig)
if err != nil { if err != nil {
return errorx.Decorate(err, "Couldn't start forwarding DNS server") return fmt.Errorf("couldn't start forwarding DNS server: %w", err)
} }
return nil return nil
@ -353,7 +352,7 @@ func stopDNSServer() error {
err := Context.dnsServer.Stop() err := Context.dnsServer.Stop()
if err != nil { if err != nil {
return errorx.Decorate(err, "Couldn't stop forwarding DNS server") return fmt.Errorf("couldn't stop forwarding DNS server: %w", err)
} }
closeDNSServer() closeDNSServer()

View File

@ -20,9 +20,7 @@ import (
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
) )
var ( var nextFilterID = time.Now().Unix() // semi-stable way to generate an unique ID
nextFilterID = time.Now().Unix() // semi-stable way to generate an unique ID
)
// Filtering - module object // Filtering - module object
type Filtering struct { type Filtering struct {
@ -35,7 +33,7 @@ type Filtering struct {
// Init - initialize the module // Init - initialize the module
func (f *Filtering) Init() { func (f *Filtering) Init() {
f.filterTitleRegexp = regexp.MustCompile(`^! Title: +(.*)$`) f.filterTitleRegexp = regexp.MustCompile(`^! Title: +(.*)$`)
_ = os.MkdirAll(filepath.Join(Context.getDataDir(), filterDir), 0755) _ = os.MkdirAll(filepath.Join(Context.getDataDir(), filterDir), 0o755)
f.loadFilters(config.Filters) f.loadFilters(config.Filters)
f.loadFilters(config.WhitelistFilters) f.loadFilters(config.WhitelistFilters)
deduplicateFilters() deduplicateFilters()
@ -466,7 +464,6 @@ func (f *Filtering) parseFilterContents(file io.Reader) (int, uint32, string) {
line = strings.TrimSpace(line) line = strings.TrimSpace(line)
if len(line) == 0 { if len(line) == 0 {
// //
} else if line[0] == '!' { } else if line[0] == '!' {
m := f.filterTitleRegexp.FindAllStringSubmatch(line, -1) m := f.filterTitleRegexp.FindAllStringSubmatch(line, -1)
if len(m) > 0 && len(m[0]) >= 2 && !seenTitle { if len(m) > 0 && len(m[0]) >= 2 && !seenTitle {
@ -476,7 +473,6 @@ func (f *Filtering) parseFilterContents(file io.Reader) (int, uint32, string) {
} else if line[0] == '#' { } else if line[0] == '#' {
// //
} else { } else {
rulesCount++ rulesCount++
} }
@ -521,7 +517,7 @@ func (f *Filtering) updateIntl(filter *filter) (bool, error) {
if filepath.IsAbs(filter.URL) { if filepath.IsAbs(filter.URL) {
f, err := os.Open(filter.URL) f, err := os.Open(filter.URL)
if err != nil { if err != nil {
return false, fmt.Errorf("open file: %s", err) return false, fmt.Errorf("open file: %w", err)
} }
defer f.Close() defer f.Close()
reader = f reader = f

View File

@ -22,11 +22,10 @@ import (
"gopkg.in/natefinch/lumberjack.v2" "gopkg.in/natefinch/lumberjack.v2"
"github.com/AdguardTeam/AdGuardHome/internal/agherr"
"github.com/AdguardTeam/AdGuardHome/internal/update" "github.com/AdguardTeam/AdGuardHome/internal/update"
"github.com/AdguardTeam/AdGuardHome/internal/util" "github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/joomcode/errorx"
"github.com/AdguardTeam/AdGuardHome/internal/isdelve" "github.com/AdguardTeam/AdGuardHome/internal/isdelve"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd" "github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
@ -113,7 +112,7 @@ func Main(version string, channel string, armVer string) {
go func() { go func() {
for { for {
sig := <-Context.appSignalChannel sig := <-Context.appSignalChannel
log.Info("Received signal '%s'", sig) log.Info("Received signal %q", sig)
switch sig { switch sig {
case syscall.SIGHUP: case syscall.SIGHUP:
Context.clients.Reload() Context.clients.Reload()
@ -279,7 +278,7 @@ func run(args options) {
} }
} }
err := os.MkdirAll(Context.getDataDir(), 0755) err := os.MkdirAll(Context.getDataDir(), 0o755)
if err != nil { if err != nil {
log.Fatalf("Cannot create DNS data dir at %s: %s", Context.getDataDir(), err) log.Fatalf("Cannot create DNS data dir at %s: %s", Context.getDataDir(), err)
} }
@ -358,7 +357,7 @@ func checkPermissions() {
// On Windows we need to have admin rights to run properly // On Windows we need to have admin rights to run properly
admin, _ := util.HaveAdminRights() admin, _ := util.HaveAdminRights()
if //noinspection ALL if // noinspection ALL
admin || isdelve.Enabled { admin || isdelve.Enabled {
// Don't forget that for this to work you need to add "delve" tag explicitly // Don't forget that for this to work you need to add "delve" tag explicitly
// https://stackoverflow.com/questions/47879070/how-can-i-see-if-the-goland-debugger-is-running-in-the-program // https://stackoverflow.com/questions/47879070/how-can-i-see-if-the-goland-debugger-is-running-in-the-program
@ -404,7 +403,7 @@ Please note, that this is crucial for a DNS server to be able to use that port.`
// Write PID to a file // Write PID to a file
func writePIDFile(fn string) bool { func writePIDFile(fn string) bool {
data := fmt.Sprintf("%d", os.Getpid()) data := fmt.Sprintf("%d", os.Getpid())
err := ioutil.WriteFile(fn, []byte(data), 0644) err := ioutil.WriteFile(fn, []byte(data), 0o644)
if err != nil { if err != nil {
log.Error("Couldn't write PID to file %s: %v", fn, err) log.Error("Couldn't write PID to file %s: %v", fn, err)
return false return false
@ -487,7 +486,7 @@ func configureLogger(args options) {
logFilePath = ls.LogFile logFilePath = ls.LogFile
} }
_, err := os.OpenFile(logFilePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) _, err := os.OpenFile(logFilePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o644)
if err != nil { if err != nil {
log.Fatalf("cannot create a log file: %s", err) log.Fatalf("cannot create a log file: %s", err)
} }
@ -498,7 +497,7 @@ func configureLogger(args options) {
LocalTime: ls.LogLocalTime, LocalTime: ls.LogLocalTime,
MaxBackups: ls.LogMaxBackups, MaxBackups: ls.LogMaxBackups,
MaxSize: ls.LogMaxSize, // megabytes MaxSize: ls.LogMaxSize, // megabytes
MaxAge: ls.LogMaxAge, //days MaxAge: ls.LogMaxAge, // days
}) })
} }
} }
@ -662,7 +661,7 @@ func customDialContext(ctx context.Context, network, addr string) (net.Conn, err
} }
return con, err return con, err
} }
return nil, errorx.DecorateMany(fmt.Sprintf("couldn't dial to %s", addr), dialErrs...) return nil, agherr.Many(fmt.Sprintf("couldn't dial to %s", addr), dialErrs...)
} }
func getHTTPProxy(req *http.Request) (*url.URL, error) { func getHTTPProxy(req *http.Request) (*url.URL, error) {

View File

@ -106,7 +106,7 @@ var portArg = arg{
var p int var p int
minPort, maxPort := 0, 1<<16-1 minPort, maxPort := 0, 1<<16-1
if p, err = strconv.Atoi(v); err != nil { if p, err = strconv.Atoi(v); err != nil {
err = fmt.Errorf("port '%s' is not a number", v) err = fmt.Errorf("port %q is not a number", v)
} else if p < minPort || p > maxPort { } else if p < minPort || p > maxPort {
err = fmt.Errorf("port %d not in range %d - %d", p, minPort, maxPort) err = fmt.Errorf("port %d not in range %d - %d", p, minPort, maxPort)
} else { } else {

View File

@ -20,7 +20,6 @@ import (
"time" "time"
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
"github.com/joomcode/errorx"
) )
var tlsWebHandlersRegistered = false var tlsWebHandlersRegistered = false
@ -484,13 +483,13 @@ func unmarshalTLS(r *http.Request) (tlsConfigSettings, error) {
data := tlsConfigSettings{} data := tlsConfigSettings{}
err := json.NewDecoder(r.Body).Decode(&data) err := json.NewDecoder(r.Body).Decode(&data)
if err != nil { if err != nil {
return data, errorx.Decorate(err, "Failed to parse new TLS config json") return data, fmt.Errorf("failed to parse new TLS config json: %w", err)
} }
if data.CertificateChain != "" { if data.CertificateChain != "" {
certPEM, err := base64.StdEncoding.DecodeString(data.CertificateChain) certPEM, err := base64.StdEncoding.DecodeString(data.CertificateChain)
if err != nil { if err != nil {
return data, errorx.Decorate(err, "Failed to base64-decode certificate chain") return data, fmt.Errorf("failed to base64-decode certificate chain: %w", err)
} }
data.CertificateChain = string(certPEM) data.CertificateChain = string(certPEM)
if data.CertificatePath != "" { if data.CertificatePath != "" {
@ -501,7 +500,7 @@ func unmarshalTLS(r *http.Request) (tlsConfigSettings, error) {
if data.PrivateKey != "" { if data.PrivateKey != "" {
keyPEM, err := base64.StdEncoding.DecodeString(data.PrivateKey) keyPEM, err := base64.StdEncoding.DecodeString(data.PrivateKey)
if err != nil { if err != nil {
return data, errorx.Decorate(err, "Failed to base64-decode private key") return data, fmt.Errorf("failed to base64-decode private key: %w", err)
} }
data.PrivateKey = string(keyPEM) data.PrivateKey = string(keyPEM)

View File

@ -184,7 +184,7 @@ func upgradeSchema2to3(diskConfig *map[string]interface{}) error {
newDNSConfig[fmt.Sprint(k)] = v newDNSConfig[fmt.Sprint(k)] = v
} }
default: default:
return fmt.Errorf("DNS configuration is not a map") return fmt.Errorf("dns configuration is not a map")
} }
// Replace bootstrap_dns value filed with new array contains old bootstrap_dns inside // Replace bootstrap_dns value filed with new array contains old bootstrap_dns inside
@ -217,7 +217,6 @@ func upgradeSchema3to4(diskConfig *map[string]interface{}) error {
case []interface{}: case []interface{}:
for i := range arr { for i := range arr {
switch c := arr[i].(type) { switch c := arr[i].(type) {
case map[interface{}]interface{}: case map[interface{}]interface{}:
@ -309,7 +308,6 @@ func upgradeSchema5to6(diskConfig *map[string]interface{}) error {
case []interface{}: case []interface{}:
for i := range arr { for i := range arr {
switch c := arr[i].(type) { switch c := arr[i].(type) {
case map[interface{}]interface{}: case map[interface{}]interface{}:

View File

@ -168,7 +168,7 @@ func (w *Whois) queryAll(target string) (string, error) {
log.Debug("Whois: redirected to %s IP:%s", redir, target) log.Debug("Whois: redirected to %s IP:%s", redir, target)
} }
return "", fmt.Errorf("Whois: redirect loop") return "", fmt.Errorf("whois: redirect loop")
} }
// Request WHOIS information // Request WHOIS information

View File

@ -3,7 +3,7 @@ package querylog
import ( import (
"io" "io"
"github.com/joomcode/errorx" "github.com/AdguardTeam/AdGuardHome/internal/agherr"
) )
// QLogReader allows reading from multiple query log files in the reverse order. // QLogReader allows reading from multiple query log files in the reverse order.
@ -132,7 +132,7 @@ func closeQFiles(qFiles []*QLogFile) error {
} }
if len(errs) > 0 { if len(errs) > 0 {
return errorx.DecorateMany("Error while closing QLogReader", errs...) return agherr.Many("Error while closing QLogReader", errs...)
} }
return nil return nil

View File

@ -32,12 +32,12 @@ func (u *Updater) GetVersionResponse(forceRecheck bool) (VersionInfo, error) {
} }
if err != nil { if err != nil {
return VersionInfo{}, fmt.Errorf("updater: HTTP GET %s: %s", u.VersionURL, err) return VersionInfo{}, fmt.Errorf("updater: HTTP GET %s: %w", u.VersionURL, err)
} }
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return VersionInfo{}, fmt.Errorf("updater: HTTP GET %s: %s", u.VersionURL, err) return VersionInfo{}, fmt.Errorf("updater: HTTP GET %s: %w", u.VersionURL, err)
} }
u.versionJSON = body u.versionJSON = body
@ -51,7 +51,7 @@ func (u *Updater) parseVersionResponse(data []byte) (VersionInfo, error) {
versionJSON := make(map[string]interface{}) versionJSON := make(map[string]interface{})
err := json.Unmarshal(data, &versionJSON) err := json.Unmarshal(data, &versionJSON)
if err != nil { if err != nil {
return info, fmt.Errorf("version.json: %s", err) return info, fmt.Errorf("version.json: %w", err)
} }
var ok1, ok2, ok3, ok4 bool var ok1, ok2, ok3, ok4 bool

View File

@ -138,13 +138,13 @@ func (u *Updater) unpack() error {
if strings.HasSuffix(pkgNameOnly, ".zip") { if strings.HasSuffix(pkgNameOnly, ".zip") {
u.unpackedFiles, err = zipFileUnpack(u.packageName, u.updateDir) u.unpackedFiles, err = zipFileUnpack(u.packageName, u.updateDir)
if err != nil { if err != nil {
return fmt.Errorf(".zip unpack failed: %s", err) return fmt.Errorf(".zip unpack failed: %w", err)
} }
} else if strings.HasSuffix(pkgNameOnly, ".tar.gz") { } else if strings.HasSuffix(pkgNameOnly, ".tar.gz") {
u.unpackedFiles, err = tarGzFileUnpack(u.packageName, u.updateDir) u.unpackedFiles, err = tarGzFileUnpack(u.packageName, u.updateDir)
if err != nil { if err != nil {
return fmt.Errorf(".tar.gz unpack failed: %s", err) return fmt.Errorf(".tar.gz unpack failed: %w", err)
} }
} else { } else {
@ -158,7 +158,7 @@ func (u *Updater) check() error {
log.Debug("updater: checking configuration") log.Debug("updater: checking configuration")
err := copyFile(u.ConfigName, filepath.Join(u.updateDir, "AdGuardHome.yaml")) err := copyFile(u.ConfigName, filepath.Join(u.updateDir, "AdGuardHome.yaml"))
if err != nil { if err != nil {
return fmt.Errorf("copyFile() failed: %s", err) return fmt.Errorf("copyFile() failed: %w", err)
} }
cmd := exec.Command(u.updateExeName, "--check-config") cmd := exec.Command(u.updateExeName, "--check-config")
err = cmd.Run() err = cmd.Run()
@ -170,10 +170,10 @@ func (u *Updater) check() error {
func (u *Updater) backup() error { func (u *Updater) backup() error {
log.Debug("updater: backing up the current configuration") log.Debug("updater: backing up the current configuration")
_ = os.Mkdir(u.backupDir, 0755) _ = os.Mkdir(u.backupDir, 0o755)
err := copyFile(u.ConfigName, filepath.Join(u.backupDir, "AdGuardHome.yaml")) err := copyFile(u.ConfigName, filepath.Join(u.backupDir, "AdGuardHome.yaml"))
if err != nil { if err != nil {
return fmt.Errorf("copyFile() failed: %s", err) return fmt.Errorf("copyFile() failed: %w", err)
} }
// workdir/README.md -> backup/README.md // workdir/README.md -> backup/README.md
@ -221,7 +221,7 @@ func (u *Updater) clean() {
func (u *Updater) downloadPackageFile(url string, filename string) error { func (u *Updater) downloadPackageFile(url string, filename string) error {
resp, err := u.Client.Get(url) resp, err := u.Client.Get(url)
if err != nil { if err != nil {
return fmt.Errorf("HTTP request failed: %s", err) return fmt.Errorf("http request failed: %w", err)
} }
if resp != nil && resp.Body != nil { if resp != nil && resp.Body != nil {
defer resp.Body.Close() defer resp.Body.Close()
@ -230,15 +230,15 @@ func (u *Updater) downloadPackageFile(url string, filename string) error {
log.Debug("updater: reading HTTP body") log.Debug("updater: reading HTTP body")
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return fmt.Errorf("ioutil.ReadAll() failed: %s", err) return fmt.Errorf("ioutil.ReadAll() failed: %w", err)
} }
_ = os.Mkdir(u.updateDir, 0755) _ = os.Mkdir(u.updateDir, 0o755)
log.Debug("updater: saving package to file") log.Debug("updater: saving package to file")
err = ioutil.WriteFile(filename, body, 0644) err = ioutil.WriteFile(filename, body, 0o644)
if err != nil { if err != nil {
return fmt.Errorf("ioutil.WriteFile() failed: %s", err) return fmt.Errorf("ioutil.WriteFile() failed: %w", err)
} }
return nil return nil
} }
@ -250,7 +250,7 @@ func (u *Updater) downloadPackageFile(url string, filename string) error {
func tarGzFileUnpack(tarfile, outdir string) ([]string, error) { func tarGzFileUnpack(tarfile, outdir string) ([]string, error) {
f, err := os.Open(tarfile) f, err := os.Open(tarfile)
if err != nil { if err != nil {
return nil, fmt.Errorf("os.Open(): %s", err) return nil, fmt.Errorf("os.Open(): %w", err)
} }
defer func() { defer func() {
_ = f.Close() _ = f.Close()
@ -258,7 +258,7 @@ func tarGzFileUnpack(tarfile, outdir string) ([]string, error) {
gzReader, err := gzip.NewReader(f) gzReader, err := gzip.NewReader(f)
if err != nil { if err != nil {
return nil, fmt.Errorf("gzip.NewReader(): %s", err) return nil, fmt.Errorf("gzip.NewReader(): %w", err)
} }
var files []string var files []string
@ -271,7 +271,7 @@ func tarGzFileUnpack(tarfile, outdir string) ([]string, error) {
break break
} }
if err != nil { if err != nil {
err2 = fmt.Errorf("tarReader.Next(): %s", err) err2 = fmt.Errorf("tarReader.Next(): %w", err)
break break
} }
@ -283,9 +283,9 @@ func tarGzFileUnpack(tarfile, outdir string) ([]string, error) {
outputName := filepath.Join(outdir, inputNameOnly) outputName := filepath.Join(outdir, inputNameOnly)
if header.Typeflag == tar.TypeDir { if header.Typeflag == tar.TypeDir {
err = os.Mkdir(outputName, os.FileMode(header.Mode&0777)) err = os.Mkdir(outputName, os.FileMode(header.Mode&0o777))
if err != nil && !os.IsExist(err) { if err != nil && !os.IsExist(err) {
err2 = fmt.Errorf("os.Mkdir(%s): %s", outputName, err) err2 = fmt.Errorf("os.Mkdir(%s): %w", outputName, err)
break break
} }
log.Debug("updater: created directory %s", outputName) log.Debug("updater: created directory %s", outputName)
@ -295,20 +295,20 @@ func tarGzFileUnpack(tarfile, outdir string) ([]string, error) {
continue continue
} }
f, err := os.OpenFile(outputName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(header.Mode&0777)) f, err := os.OpenFile(outputName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(header.Mode&0o777))
if err != nil { if err != nil {
err2 = fmt.Errorf("os.OpenFile(%s): %s", outputName, err) err2 = fmt.Errorf("os.OpenFile(%s): %w", outputName, err)
break break
} }
_, err = io.Copy(f, tarReader) _, err = io.Copy(f, tarReader)
if err != nil { if err != nil {
_ = f.Close() _ = f.Close()
err2 = fmt.Errorf("io.Copy(): %s", err) err2 = fmt.Errorf("io.Copy(): %w", err)
break break
} }
err = f.Close() err = f.Close()
if err != nil { if err != nil {
err2 = fmt.Errorf("f.Close(): %s", err) err2 = fmt.Errorf("f.Close(): %w", err)
break break
} }
@ -327,7 +327,7 @@ func tarGzFileUnpack(tarfile, outdir string) ([]string, error) {
func zipFileUnpack(zipfile, outdir string) ([]string, error) { func zipFileUnpack(zipfile, outdir string) ([]string, error) {
r, err := zip.OpenReader(zipfile) r, err := zip.OpenReader(zipfile)
if err != nil { if err != nil {
return nil, fmt.Errorf("zip.OpenReader(): %s", err) return nil, fmt.Errorf("zip.OpenReader(): %w", err)
} }
defer r.Close() defer r.Close()
@ -337,7 +337,7 @@ func zipFileUnpack(zipfile, outdir string) ([]string, error) {
for _, zf := range r.File { for _, zf := range r.File {
zr, err = zf.Open() zr, err = zf.Open()
if err != nil { if err != nil {
err2 = fmt.Errorf("zip file Open(): %s", err) err2 = fmt.Errorf("zip file Open(): %w", err)
break break
} }
@ -352,7 +352,7 @@ func zipFileUnpack(zipfile, outdir string) ([]string, error) {
if fi.IsDir() { if fi.IsDir() {
err = os.Mkdir(outputName, fi.Mode()) err = os.Mkdir(outputName, fi.Mode())
if err != nil && !os.IsExist(err) { if err != nil && !os.IsExist(err) {
err2 = fmt.Errorf("os.Mkdir(): %s", err) err2 = fmt.Errorf("os.Mkdir(): %w", err)
break break
} }
log.Tracef("created directory %s", outputName) log.Tracef("created directory %s", outputName)
@ -361,18 +361,18 @@ func zipFileUnpack(zipfile, outdir string) ([]string, error) {
f, err := os.OpenFile(outputName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, fi.Mode()) f, err := os.OpenFile(outputName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, fi.Mode())
if err != nil { if err != nil {
err2 = fmt.Errorf("os.OpenFile(): %s", err) err2 = fmt.Errorf("os.OpenFile(): %w", err)
break break
} }
_, err = io.Copy(f, zr) _, err = io.Copy(f, zr)
if err != nil { if err != nil {
_ = f.Close() _ = f.Close()
err2 = fmt.Errorf("io.Copy(): %s", err) err2 = fmt.Errorf("io.Copy(): %w", err)
break break
} }
err = f.Close() err = f.Close()
if err != nil { if err != nil {
err2 = fmt.Errorf("f.Close(): %s", err) err2 = fmt.Errorf("f.Close(): %w", err)
break break
} }
@ -390,7 +390,7 @@ func copyFile(src, dst string) error {
if e != nil { if e != nil {
return e return e
} }
e = ioutil.WriteFile(dst, d, 0644) e = ioutil.WriteFile(dst, d, 0o644)
if e != nil { if e != nil {
return e return e
} }

View File

@ -11,8 +11,6 @@ import (
"time" "time"
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
"github.com/joomcode/errorx"
) )
// NetInterface represents a list of network interfaces // NetInterface represents a list of network interfaces
@ -30,7 +28,7 @@ type NetInterface struct {
func GetValidNetInterfaces() ([]net.Interface, error) { func GetValidNetInterfaces() ([]net.Interface, error) {
ifaces, err := net.Interfaces() ifaces, err := net.Interfaces()
if err != nil { if err != nil {
return nil, fmt.Errorf("couldn't get list of interfaces: %s", err) return nil, fmt.Errorf("couldn't get list of interfaces: %w", err)
} }
netIfaces := []net.Interface{} netIfaces := []net.Interface{}
@ -48,7 +46,7 @@ func GetValidNetInterfaces() ([]net.Interface, error) {
func GetValidNetInterfacesForWeb() ([]NetInterface, error) { func GetValidNetInterfacesForWeb() ([]NetInterface, error) {
ifaces, err := GetValidNetInterfaces() ifaces, err := GetValidNetInterfaces()
if err != nil { if err != nil {
return nil, errorx.Decorate(err, "Couldn't get interfaces") return nil, fmt.Errorf("couldn't get interfaces: %w", err)
} }
if len(ifaces) == 0 { if len(ifaces) == 0 {
return nil, errors.New("couldn't find any legible interface") return nil, errors.New("couldn't find any legible interface")
@ -57,9 +55,9 @@ func GetValidNetInterfacesForWeb() ([]NetInterface, error) {
var netInterfaces []NetInterface var netInterfaces []NetInterface
for _, iface := range ifaces { for _, iface := range ifaces {
addrs, e := iface.Addrs() addrs, err := iface.Addrs()
if e != nil { if err != nil {
return nil, errorx.Decorate(e, "Failed to get addresses for interface %s", iface.Name) return nil, fmt.Errorf("failed to get addresses for interface %s: %w", iface.Name, err)
} }
netIface := NetInterface{ netIface := NetInterface{