Pull request:* all: fix all staticcheck simplification and unused warnings

Merge in DNS/adguard-home from 2270-fix-s-u-warnings to master

Squashed commit of the following:

commit 03e0f78bd471057007c2d4042ee26eda2bbc9b29
Merge: 50dc3ef5c 7e16fda57
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Fri Nov 6 11:54:09 2020 +0300

    Merge branch 'master' into 2270-fix-s-u-warnings

commit 50dc3ef5c44a5fdc941794c26784b0c44d7b5aa0
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Nov 5 19:48:54 2020 +0300

    * all: improve code quality

commit d6d804f759ce3e47154a389b427550e72c4b9090
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Nov 5 18:03:35 2020 +0300

    * all: fix all staticcheck simplification and unused warnings

    Closes #2270.
This commit is contained in:
Eugene Burkov 2020-11-06 12:15:08 +03:00
parent 7e16fda57b
commit 3e1f922252
24 changed files with 159 additions and 210 deletions

View File

@ -302,17 +302,17 @@ func (s *Server) handleDHCPInterfaces(w http.ResponseWriter, r *http.Request) {
func (s *Server) handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Request) { func (s *Server) handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
errorText := fmt.Sprintf("failed to read request body: %s", err) msg := fmt.Sprintf("failed to read request body: %s", err)
log.Error(errorText) log.Error(msg)
http.Error(w, errorText, http.StatusBadRequest) http.Error(w, msg, http.StatusBadRequest)
return return
} }
interfaceName := strings.TrimSpace(string(body)) interfaceName := strings.TrimSpace(string(body))
if interfaceName == "" { if interfaceName == "" {
errorText := fmt.Sprintf("empty interface name specified") msg := "empty interface name specified"
log.Error(errorText) log.Error(msg)
http.Error(w, errorText, http.StatusBadRequest) http.Error(w, msg, http.StatusBadRequest)
return return
} }
@ -370,7 +370,6 @@ func (s *Server) handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Reque
} }
func (s *Server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request) { func (s *Server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request) {
lj := staticLeaseJSON{} lj := staticLeaseJSON{}
err := json.NewDecoder(r.Body).Decode(&lj) err := json.NewDecoder(r.Body).Decode(&lj)
if err != nil { if err != nil {
@ -424,7 +423,6 @@ func (s *Server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request
} }
func (s *Server) handleDHCPRemoveStaticLease(w http.ResponseWriter, r *http.Request) { func (s *Server) handleDHCPRemoveStaticLease(w http.ResponseWriter, r *http.Request) {
lj := staticLeaseJSON{} lj := staticLeaseJSON{}
err := json.NewDecoder(r.Body).Decode(&lj) err := json.NewDecoder(r.Body).Decode(&lj)
if err != nil { if err != nil {

View File

@ -12,12 +12,6 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func check(t *testing.T, result bool, msg string) {
if !result {
t.Fatal(msg)
}
}
func testNotify(flags uint32) { func testNotify(flags uint32) {
} }

View File

@ -48,14 +48,12 @@ const (
ServerPort = 67 ServerPort = 67
) )
var ( // DefaultServers is the address of all link-local DHCP servers and
// DefaultServers is the address of all link-local DHCP servers and // relay agents.
// relay agents. var DefaultServers = &net.UDPAddr{
DefaultServers = &net.UDPAddr{ IP: net.IPv4bcast,
IP: net.IPv4bcast, Port: ServerPort,
Port: ServerPort, }
}
)
var ( var (
// ErrNoResponse is returned when no response packet is received. // ErrNoResponse is returned when no response packet is received.
@ -375,14 +373,6 @@ func WithHWAddr(hwAddr net.HardwareAddr) ClientOpt {
} }
} }
// nolint
func withBufferCap(n int) ClientOpt {
return func(c *Client) (err error) {
c.bufferCap = n
return
}
}
// WithRetry configures the number of retransmissions to attempt. // WithRetry configures the number of retransmissions to attempt.
// //
// Default is 3. // Default is 3.

View File

@ -122,6 +122,13 @@ func newPacket(op dhcpv4.OpcodeType, xid dhcpv4.TransactionID) *dhcpv4.DHCPv4 {
return p return p
} }
func withBufferCap(n int) ClientOpt {
return func(c *Client) (err error) {
c.bufferCap = n
return
}
}
func TestSendAndRead(t *testing.T) { func TestSendAndRead(t *testing.T) {
for _, tt := range []struct { for _, tt := range []struct {
desc string desc string

View File

@ -73,7 +73,6 @@ func hasStaticIPDhcpcdConf(dhcpConf, ifaceName string) bool {
// we found our interface // we found our interface
withinInterfaceCtx = true withinInterfaceCtx = true
} }
} else { } else {
if strings.HasPrefix(line, "interface ") { if strings.HasPrefix(line, "interface ") {
// we found another interface - reset our state // we found another interface - reset our state
@ -240,7 +239,7 @@ func getNetworkSetupHardwareReports() map[string]string {
return nil return nil
} }
m := make(map[string]string, 0) m := make(map[string]string)
matches := re.FindAllStringSubmatch(out, -1) matches := re.FindAllStringSubmatch(out, -1)
for i := range matches { for i := range matches {

View File

@ -41,7 +41,7 @@ func (s *v6Server) WriteDiskConfig6(c *V6ServerConf) {
// Return TRUE if IP address is within range [start..0xff] // Return TRUE if IP address is within range [start..0xff]
// nolint(staticcheck) // nolint(staticcheck)
func ip6InRange(start net.IP, ip net.IP) bool { func ip6InRange(start, ip net.IP) bool {
if len(start) != 16 { if len(start) != 16 {
return false return false
} }
@ -369,7 +369,7 @@ func (s *v6Server) commitLease(msg *dhcpv6.Message, lease *Lease) time.Duration
// //
case dhcpv6.MessageTypeConfirm: case dhcpv6.MessageTypeConfirm:
lifetime = lease.Expiry.Sub(time.Now()) lifetime = time.Until(lease.Expiry)
case dhcpv6.MessageTypeRequest, case dhcpv6.MessageTypeRequest,
dhcpv6.MessageTypeRenew, dhcpv6.MessageTypeRenew,
@ -383,7 +383,7 @@ func (s *v6Server) commitLease(msg *dhcpv6.Message, lease *Lease) time.Duration
} }
// Find a lease associated with MAC and prepare response // Find a lease associated with MAC and prepare response
func (s *v6Server) process(msg *dhcpv6.Message, req dhcpv6.DHCPv6, resp dhcpv6.DHCPv6) bool { func (s *v6Server) process(msg *dhcpv6.Message, req, resp dhcpv6.DHCPv6) bool {
switch msg.Type() { switch msg.Type() {
case dhcpv6.MessageTypeSolicit, case dhcpv6.MessageTypeSolicit,
dhcpv6.MessageTypeRequest, dhcpv6.MessageTypeRequest,

View File

@ -199,7 +199,7 @@ func (d *Dnsfilter) WriteDiskConfig(c *Config) {
// SetFilters - set new filters (synchronously or asynchronously) // SetFilters - set new filters (synchronously or asynchronously)
// When filters are set asynchronously, the old filters continue working until the new filters are ready. // When filters are set asynchronously, the old filters continue working until the new filters are ready.
// In this case the caller must ensure that the old filter files are intact. // In this case the caller must ensure that the old filter files are intact.
func (d *Dnsfilter) SetFilters(blockFilters []Filter, allowFilters []Filter, async bool) error { func (d *Dnsfilter) SetFilters(blockFilters, allowFilters []Filter, async bool) error {
if async { if async {
params := filtersInitializerParams{ params := filtersInitializerParams{
allowFilters: allowFilters, allowFilters: allowFilters,
@ -481,13 +481,10 @@ func matchBlockedServicesRules(host string, svcs []ServiceEntry) Result {
// Adding rule and matching against the rules // Adding rule and matching against the rules
// //
// Return TRUE if file exists // fileExists returns true if file exists.
func fileExists(fn string) bool { func fileExists(fn string) bool {
_, err := os.Stat(fn) _, err := os.Stat(fn)
if err != nil { return err == nil
return false
}
return true
} }
func createFilteringEngine(filters []Filter) (*filterlist.RuleStorage, *urlfilter.DNSEngine, error) { func createFilteringEngine(filters []Filter) (*filterlist.RuleStorage, *urlfilter.DNSEngine, error) {
@ -508,7 +505,8 @@ func createFilteringEngine(filters []Filter) (*filterlist.RuleStorage, *urlfilte
} }
} 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: %w", f.FilePath, err) return nil, nil, fmt.Errorf("ioutil.ReadFile(): %s: %w", f.FilePath, err)
@ -537,7 +535,7 @@ func createFilteringEngine(filters []Filter) (*filterlist.RuleStorage, *urlfilte
return rulesStorage, filteringEngine, nil return rulesStorage, filteringEngine, nil
} }
// Initialize urlfilter objects // Initialize urlfilter objects.
func (d *Dnsfilter) initFiltering(allowFilters, blockFilters []Filter) error { func (d *Dnsfilter) initFiltering(allowFilters, blockFilters []Filter) error {
rulesStorage, filteringEngine, err := createFilteringEngine(blockFilters) rulesStorage, filteringEngine, err := createFilteringEngine(blockFilters)
if err != nil { if err != nil {
@ -563,7 +561,8 @@ func (d *Dnsfilter) initFiltering(allowFilters, blockFilters []Filter) error {
return nil return nil
} }
// matchHost is a low-level way to check only if hostname is filtered by rules, skipping expensive safebrowsing and parental lookups // matchHost is a low-level way to check only if hostname is filtered by rules,
// skipping expensive safebrowsing and parental lookups.
func (d *Dnsfilter) matchHost(host string, qtype uint16, setts RequestFilteringSettings) (Result, error) { func (d *Dnsfilter) matchHost(host string, qtype uint16, setts RequestFilteringSettings) (Result, error) {
d.engineLock.RLock() d.engineLock.RLock()
// Keep in mind that this lock must be held no just when calling Match() // Keep in mind that this lock must be held no just when calling Match()
@ -664,20 +663,18 @@ func makeResult(rule rules.Rule, reason Reason) Result {
return res return res
} }
// InitModule() - manually initialize blocked services map // InitModule manually initializes blocked services map.
func InitModule() { func InitModule() {
initBlockedServices() initBlockedServices()
} }
// 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,
} }
// initialize objects only once
if gctx.safebrowsingCache == nil { if gctx.safebrowsingCache == nil {
cacheConf.MaxSize = c.SafeBrowsingCacheSize cacheConf.MaxSize = c.SafeBrowsingCacheSize
gctx.safebrowsingCache = cache.New(cacheConf) gctx.safebrowsingCache = cache.New(cacheConf)
@ -747,7 +744,7 @@ func (d *Dnsfilter) Start() {
// stats // stats
// //
// GetStats return dns filtering stats since startup // GetStats return dns filtering stats since startup.
func (d *Dnsfilter) GetStats() Stats { func (d *Dnsfilter) GetStats() Stats {
return gctx.stats return gctx.stats
} }

View File

@ -3,9 +3,6 @@ package dnsfilter
import ( import (
"fmt" "fmt"
"net" "net"
"os"
"path"
"runtime"
"testing" "testing"
"github.com/AdguardTeam/urlfilter/rules" "github.com/AdguardTeam/urlfilter/rules"
@ -36,13 +33,6 @@ func purgeCaches() {
} }
} }
func _Func() string {
pc := make([]uintptr, 10) // at least 1 entry needed
runtime.Callers(2, pc)
f := runtime.FuncForPC(pc[0])
return path.Base(f.Name())
}
func NewForTest(c *Config, filters []Filter) *Dnsfilter { func NewForTest(c *Config, filters []Filter) *Dnsfilter {
setts = RequestFilteringSettings{} setts = RequestFilteringSettings{}
setts.FilteringEnabled = true setts.FilteringEnabled = true
@ -71,7 +61,7 @@ func (d *Dnsfilter) checkMatch(t *testing.T, hostname string) {
} }
} }
func (d *Dnsfilter) checkMatchIP(t *testing.T, hostname string, ip string, qtype uint16) { func (d *Dnsfilter) checkMatchIP(t *testing.T, hostname, ip string, qtype uint16) {
t.Helper() t.Helper()
ret, err := d.CheckHost(hostname, qtype, &setts) ret, err := d.CheckHost(hostname, qtype, &setts)
if err != nil { if err != nil {
@ -107,7 +97,7 @@ func TestEtcHostsMatching(t *testing.T) {
::1 host2 ::1 host2
`, `,
addr, addr6) addr, addr6)
filters := []Filter{Filter{ filters := []Filter{{
ID: 0, Data: []byte(text), ID: 0, Data: []byte(text),
}} }}
d := NewForTest(nil, filters) d := NewForTest(nil, filters)
@ -351,11 +341,15 @@ func TestParentalControl(t *testing.T) {
// FILTERING // FILTERING
var blockingRules = "||example.org^\n" const nl = "\n"
var whitelistRules = "||example.org^\n@@||test.example.org\n"
var importantRules = "@@||example.org^\n||test.example.org^$important\n" const (
var regexRules = "/example\\.org/\n@@||test.example.org^\n" blockingRules = `||example.org^` + nl
var maskRules = "test*.example.org^\nexam*.com\n" whitelistRules = `||example.org^` + nl + `@@||test.example.org` + nl
importantRules = `@@||example.org^` + nl + `||test.example.org^$important` + nl
regexRules = `/example\.org/` + nl + `@@||test.example.org^` + nl
maskRules = `test*.example.org^` + nl + `exam*.com` + nl
)
var tests = []struct { var tests = []struct {
testname string testname string
@ -406,7 +400,7 @@ var tests = []struct {
func TestMatching(t *testing.T) { func TestMatching(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(fmt.Sprintf("%s-%s", test.testname, test.hostname), func(t *testing.T) { t.Run(fmt.Sprintf("%s-%s", test.testname, test.hostname), func(t *testing.T) {
filters := []Filter{Filter{ filters := []Filter{{
ID: 0, Data: []byte(test.rules), ID: 0, Data: []byte(test.rules),
}} }}
d := NewForTest(nil, filters) d := NewForTest(nil, filters)
@ -430,14 +424,14 @@ func TestWhitelist(t *testing.T) {
rules := `||host1^ rules := `||host1^
||host2^ ||host2^
` `
filters := []Filter{Filter{ filters := []Filter{{
ID: 0, Data: []byte(rules), ID: 0, Data: []byte(rules),
}} }}
whiteRules := `||host1^ whiteRules := `||host1^
||host3^ ||host3^
` `
whiteFilters := []Filter{Filter{ whiteFilters := []Filter{{
ID: 0, Data: []byte(whiteRules), ID: 0, Data: []byte(whiteRules),
}} }}
d := NewForTest(nil, filters) d := NewForTest(nil, filters)
@ -455,7 +449,6 @@ func TestWhitelist(t *testing.T) {
assert.True(t, err == nil) assert.True(t, err == nil)
assert.True(t, ret.IsFiltered && ret.Reason == FilteredBlackList) assert.True(t, ret.IsFiltered && ret.Reason == FilteredBlackList)
assert.True(t, ret.Rule == "||host2^") assert.True(t, ret.Rule == "||host2^")
} }
// CLIENT SETTINGS // CLIENT SETTINGS
@ -476,7 +469,7 @@ func applyClientSettings(setts *RequestFilteringSettings) {
// then apply per-client settings and check behaviour once again // then apply per-client settings and check behaviour once again
func TestClientSettings(t *testing.T) { func TestClientSettings(t *testing.T) {
var r Result var r Result
filters := []Filter{Filter{ filters := []Filter{{
ID: 0, Data: []byte("||example.org^\n"), ID: 0, Data: []byte("||example.org^\n"),
}} }}
d := NewForTest(&Config{ParentalEnabled: true, SafeBrowsingEnabled: false}, filters) d := NewForTest(&Config{ParentalEnabled: true, SafeBrowsingEnabled: false}, filters)
@ -532,13 +525,6 @@ func TestClientSettings(t *testing.T) {
assert.True(t, r.IsFiltered && r.Reason == FilteredBlockedService) assert.True(t, r.IsFiltered && r.Reason == FilteredBlockedService)
} }
func prepareTestDir() string {
const dir = "./agh-test"
_ = os.RemoveAll(dir)
_ = os.MkdirAll(dir, 0755)
return dir
}
// BENCHMARKS // BENCHMARKS
func BenchmarkSafeBrowsing(b *testing.B) { func BenchmarkSafeBrowsing(b *testing.B) {

View File

@ -22,8 +22,7 @@ func (d *Dnsfilter) setCacheResult(cache cache.Cache, host string, res Result) i
var buf bytes.Buffer var buf bytes.Buffer
expire := uint(time.Now().Unix()) + d.Config.CacheTime*60 expire := uint(time.Now().Unix()) + d.Config.CacheTime*60
var exp []byte exp := make([]byte, 4)
exp = make([]byte, 4)
binary.BigEndian.PutUint32(exp, uint32(expire)) binary.BigEndian.PutUint32(exp, uint32(expire))
_, _ = buf.Write(exp) _, _ = buf.Write(exp)

View File

@ -22,11 +22,13 @@ import (
"golang.org/x/net/publicsuffix" "golang.org/x/net/publicsuffix"
) )
const dnsTimeout = 3 * time.Second const (
const defaultSafebrowsingServer = "https://dns-family.adguard.com/dns-query" dnsTimeout = 3 * time.Second
const defaultParentalServer = "https://dns-family.adguard.com/dns-query" defaultSafebrowsingServer = `https://dns-family.adguard.com/dns-query`
const sbTXTSuffix = "sb.dns.adguard.com." defaultParentalServer = `https://dns-family.adguard.com/dns-query`
const pcTXTSuffix = "pc.dns.adguard.com." sbTXTSuffix = `sb.dns.adguard.com.`
pcTXTSuffix = `pc.dns.adguard.com.`
)
func (d *Dnsfilter) initSecurityServices() error { func (d *Dnsfilter) initSecurityServices() error {
var err error var err error
@ -60,7 +62,7 @@ expire byte[4]
hash byte[32] hash byte[32]
... ...
*/ */
func (c *sbCtx) setCache(prefix []byte, hashes []byte) { func (c *sbCtx) setCache(prefix, hashes []byte) {
d := make([]byte, 4+len(hashes)) d := make([]byte, 4+len(hashes))
expire := uint(time.Now().Unix()) + c.cacheTime*60 expire := uint(time.Now().Unix()) + c.cacheTime*60
binary.BigEndian.PutUint32(d[:4], uint32(expire)) binary.BigEndian.PutUint32(d[:4], uint32(expire))
@ -158,16 +160,28 @@ func hostnameToHashes(host string) map[[32]byte]string {
// convert hash array to string // convert hash array to string
func (c *sbCtx) getQuestion() string { func (c *sbCtx) getQuestion() string {
q := "" b := &strings.Builder{}
encoder := hex.NewEncoder(b)
for hash := range c.hashToHost { for hash := range c.hashToHost {
q += fmt.Sprintf("%s.", hex.EncodeToString(hash[0:2])) // Ignore errors, since strings.(*Buffer).Write never returns
// errors.
//
// TODO(e.burkov, a.garipov): Find out and document why exactly
// this slice.
_, _ = encoder.Write(hash[0:2])
_, _ = b.WriteRune('.')
} }
if c.svc == "SafeBrowsing" { if c.svc == "SafeBrowsing" {
q += sbTXTSuffix // See comment above.
} else { _, _ = b.WriteString(sbTXTSuffix)
q += pcTXTSuffix return b.String()
} }
return q
// See comment above.
_, _ = b.WriteString(pcTXTSuffix)
return b.String()
} }
// Find the target hash in TXT response // Find the target hash in TXT response

View File

@ -23,16 +23,16 @@ func TestSafeBrowsingHash(t *testing.T) {
assert.False(t, ok) assert.False(t, ok)
c := &sbCtx{ c := &sbCtx{
svc: "SafeBrowsing", svc: "SafeBrowsing",
hashToHost: hashes,
} }
// test getQuestion()
c.hashToHost = hashes
q := c.getQuestion() q := c.getQuestion()
assert.True(t, strings.Index(q, "7a1b.") >= 0)
assert.True(t, strings.Index(q, "af5a.") >= 0) assert.True(t, strings.Contains(q, "7a1b."))
assert.True(t, strings.Index(q, "eb11.") >= 0) assert.True(t, strings.Contains(q, "af5a."))
assert.True(t, strings.Index(q, "sb.dns.adguard.com.") > 0) assert.True(t, strings.Contains(q, "eb11."))
assert.True(t, strings.HasSuffix(q, "sb.dns.adguard.com."))
} }
func TestSafeBrowsingCache(t *testing.T) { func TestSafeBrowsingCache(t *testing.T) {

View File

@ -27,14 +27,12 @@ type session struct {
expire uint32 // expiration time (in seconds) expire uint32 // expiration time (in seconds)
} }
/*
expire byte[4]
name_len byte[2]
name byte[]
*/
func (s *session) serialize() []byte { func (s *session) serialize() []byte {
var data []byte const (
data = make([]byte, 4+2+len(s.userName)) expireLen = 4
nameLen = 2
)
data := make([]byte, expireLen+nameLen+len(s.userName))
binary.BigEndian.PutUint32(data[0:4], s.expire) binary.BigEndian.PutUint32(data[0:4], s.expire)
binary.BigEndian.PutUint16(data[4:6], uint16(len(s.userName))) binary.BigEndian.PutUint16(data[4:6], uint16(len(s.userName)))
copy(data[6:], []byte(s.userName)) copy(data[6:], []byte(s.userName))
@ -474,7 +472,7 @@ func (a *Auth) UserAdd(u *User, password string) {
} }
// UserFind - find a user // UserFind - find a user
func (a *Auth) UserFind(login string, password string) User { func (a *Auth) UserFind(login, password string) User {
a.lock.Lock() a.lock.Lock()
defer a.lock.Unlock() defer a.lock.Unlock()
for _, u := range a.users { for _, u := range a.users {

View File

@ -16,7 +16,6 @@ import (
"time" "time"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter" "github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
) )
@ -548,8 +547,10 @@ func (f *Filtering) updateIntl(filter *filter) (bool, error) {
total += n total += n
if htmlTest { if htmlTest {
// gather full buffer firstChunk and perform its data tests num := len(firstChunk) - firstChunkLen
num := util.MinInt(n, len(firstChunk)-firstChunkLen) if n < num {
num = n
}
copied := copy(firstChunk[firstChunkLen:], buf[:num]) copied := copy(firstChunk[firstChunkLen:], buf[:num])
firstChunkLen += copied firstChunkLen += copied
@ -559,8 +560,7 @@ func (f *Filtering) updateIntl(filter *filter) (bool, error) {
} }
s := strings.ToLower(string(firstChunk)) s := strings.ToLower(string(firstChunk))
if strings.Index(s, "<html") >= 0 || if strings.Contains(s, "<html") || strings.Contains(s, "<!doctype") {
strings.Index(s, "<!doctype") >= 0 {
return false, fmt.Errorf("data is HTML, not plain text") return false, fmt.Errorf("data is HTML, not plain text")
} }

View File

@ -96,7 +96,7 @@ func (c *homeContext) getDataDir() string {
var Context homeContext var Context homeContext
// Main is the entry point // Main is the entry point
func Main(version string, channel string, armVer string) { func Main(version, channel, armVer string) {
// Init update-related global variables // Init update-related global variables
versionString = version versionString = version
updateChannel = channel updateChannel = channel
@ -616,11 +616,7 @@ func detectFirstRun() bool {
configfile = filepath.Join(Context.workDir, Context.configFilename) configfile = filepath.Join(Context.workDir, Context.configFilename)
} }
_, err := os.Stat(configfile) _, err := os.Stat(configfile)
if !os.IsNotExist(err) { return os.IsNotExist(err)
// do nothing, file exists
return false
}
return true
} }
// Connect to a remote server resolving hostname using our own DNS server // Connect to a remote server resolving hostname using our own DNS server

View File

@ -58,9 +58,9 @@ func handleI18nCurrentLanguage(w http.ResponseWriter, r *http.Request) {
log.Printf("config.Language is %s", config.Language) log.Printf("config.Language is %s", config.Language)
_, err := fmt.Fprintf(w, "%s\n", config.Language) _, err := fmt.Fprintf(w, "%s\n", config.Language)
if err != nil { if err != nil {
errorText := fmt.Sprintf("Unable to write response json: %s", err) msg := fmt.Sprintf("Unable to write response json: %s", err)
log.Println(errorText) log.Println(msg)
http.Error(w, errorText, http.StatusInternalServerError) http.Error(w, msg, http.StatusInternalServerError)
return return
} }
} }
@ -68,23 +68,23 @@ func handleI18nCurrentLanguage(w http.ResponseWriter, r *http.Request) {
func handleI18nChangeLanguage(w http.ResponseWriter, r *http.Request) { func handleI18nChangeLanguage(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
errorText := fmt.Sprintf("failed to read request body: %s", err) msg := fmt.Sprintf("failed to read request body: %s", err)
log.Println(errorText) log.Println(msg)
http.Error(w, errorText, http.StatusBadRequest) http.Error(w, msg, http.StatusBadRequest)
return return
} }
language := strings.TrimSpace(string(body)) language := strings.TrimSpace(string(body))
if language == "" { if language == "" {
errorText := fmt.Sprintf("empty language specified") msg := "empty language specified"
log.Println(errorText) log.Println(msg)
http.Error(w, errorText, http.StatusBadRequest) http.Error(w, msg, http.StatusBadRequest)
return return
} }
if !isLanguageAllowed(language) { if !isLanguageAllowed(language) {
errorText := fmt.Sprintf("unknown language specified: %s", language) msg := fmt.Sprintf("unknown language specified: %s", language)
log.Println(errorText) log.Println(msg)
http.Error(w, errorText, http.StatusBadRequest) http.Error(w, msg, http.StatusBadRequest)
return return
} }

View File

@ -32,13 +32,9 @@ func memoryUsage(args options) {
// that the OS could reclaim the free memory // that the OS could reclaim the free memory
go func() { go func() {
ticker := time.NewTicker(5 * time.Minute) ticker := time.NewTicker(5 * time.Minute)
for { for range ticker.C {
select { log.Debug("free os memory")
case t := <-ticker.C: debug.FreeOSMemory()
t.Second()
log.Debug("Free OS memory")
debug.FreeOSMemory()
}
} }
}() }()
} }

View File

@ -116,8 +116,7 @@ func (r *RDNS) resolve(ip string) string {
// Add the hostname:IP pair to "Clients" array // Add the hostname:IP pair to "Clients" array
func (r *RDNS) workerLoop() { func (r *RDNS) workerLoop() {
for { for {
var ip string ip := <-r.ipChannel
ip = <-r.ipChannel
host := r.resolve(ip) host := r.resolve(ip)
if len(host) == 0 { if len(host) == 0 {

View File

@ -203,7 +203,7 @@ func handleServiceInstallCommand(s service.Service) {
log.Fatal(err) log.Fatal(err)
} }
if util.IsOpenWrt() { if util.IsOpenWRT() {
// On OpenWrt it is important to run enable after the service installation // On OpenWrt it is important to run enable after the service installation
// Otherwise, the service won't start on the system startup // Otherwise, the service won't start on the system startup
_, err := runInitdCommand("enable") _, err := runInitdCommand("enable")
@ -230,7 +230,7 @@ Click on the link below and follow the Installation Wizard steps to finish setup
// handleServiceStatusCommand handles service "uninstall" command // handleServiceStatusCommand handles service "uninstall" command
func handleServiceUninstallCommand(s service.Service) { func handleServiceUninstallCommand(s service.Service) {
if util.IsOpenWrt() { if util.IsOpenWRT() {
// On OpenWrt it is important to run disable command first // On OpenWrt it is important to run disable command first
// as it will remove the symlink // as it will remove the symlink
_, err := runInitdCommand("disable") _, err := runInitdCommand("disable")
@ -272,14 +272,14 @@ func configureService(c *service.Config) {
// Redirect StdErr & StdOut to files. // Redirect StdErr & StdOut to files.
c.Option["LogOutput"] = true c.Option["LogOutput"] = true
// Use modified service file templates // Use modified service file templates.
c.Option["SystemdScript"] = systemdScript c.Option["SystemdScript"] = systemdScript
c.Option["SysvScript"] = sysvScript c.Option["SysvScript"] = sysvScript
// On OpenWrt we're using a different type of sysvScript // On OpenWrt we're using a different type of sysvScript.
if util.IsOpenWrt() { if util.IsOpenWRT() {
c.Option["SysvScript"] = openWrtScript c.Option["SysvScript"] = openWrtScript
} else if util.IsFreeBSD() { } else if runtime.GOOS == "freebsd" {
c.Option["SysvScript"] = freeBSDScript c.Option["SysvScript"] = freeBSDScript
} }
} }
@ -502,6 +502,7 @@ status() {
fi fi
} }
` `
const freeBSDScript = `#!/bin/sh const freeBSDScript = `#!/bin/sh
# PROVIDE: {{.Name}} # PROVIDE: {{.Name}}
# REQUIRE: networking # REQUIRE: networking

View File

@ -305,7 +305,7 @@ func (t *TLSMod) handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
} }
} }
func verifyCertChain(data *tlsConfigStatus, certChain string, serverName string) error { func verifyCertChain(data *tlsConfigStatus, certChain, serverName string) error {
log.Tracef("TLS: got certificate: %d bytes", len(certChain)) log.Tracef("TLS: got certificate: %d bytes", len(certChain))
// now do a more extended validation // now do a more extended validation
@ -335,7 +335,7 @@ func verifyCertChain(data *tlsConfigStatus, certChain string, serverName string)
} }
if len(parsedCerts) == 0 { if len(parsedCerts) == 0 {
data.WarningValidation = fmt.Sprintf("You have specified an empty certificate") data.WarningValidation = "You have specified an empty certificate"
return errors.New(data.WarningValidation) return errors.New(data.WarningValidation)
} }

View File

@ -116,7 +116,7 @@ func whoisParse(data string) map[string]string {
} }
// Send request to a server and receive the response // Send request to a server and receive the response
func (w *Whois) query(target string, serverAddr string) (string, error) { func (w *Whois) query(target, serverAddr string) (string, error) {
addr, _, _ := net.SplitHostPort(serverAddr) addr, _, _ := net.SplitHostPort(serverAddr)
if addr == "whois.arin.net" { if addr == "whois.arin.net" {
target = "n + " + target target = "n + " + target
@ -224,8 +224,7 @@ func (w *Whois) Begin(ip string) {
// Get IP address from channel; get WHOIS info; associate info with a client // Get IP address from channel; get WHOIS info; associate info with a client
func (w *Whois) workerLoop() { func (w *Whois) workerLoop() {
for { for {
var ip string ip := <-w.ipChan
ip = <-w.ipChan
info := w.process(ip) info := w.process(ip)
if len(info) == 0 { if len(info) == 0 {

View File

@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func UIntArrayEquals(a []uint64, b []uint64) bool { func UIntArrayEquals(a, b []uint64) bool {
if len(a) != len(b) { if len(a) != len(b) {
return false return false
} }
@ -83,8 +83,7 @@ func TestStats(t *testing.T) {
} }
func TestLargeNumbers(t *testing.T) { func TestLargeNumbers(t *testing.T) {
var hour int32 var hour int32 = 1
hour = 1
newID := func() uint32 { newID := func() uint32 {
// use "atomic" to make Go race detector happy // use "atomic" to make Go race detector happy
return uint32(atomic.LoadInt32(&hour)) return uint32(atomic.LoadInt32(&hour))
@ -144,6 +143,7 @@ func aggregateDataPerDay(firstID uint32) int {
} }
return len(a) return len(a)
} }
func TestAggregateDataPerTimeUnit(t *testing.T) { func TestAggregateDataPerTimeUnit(t *testing.T) {
for i := 0; i != 25; i++ { for i := 0; i != 25; i++ {
alen := aggregateDataPerDay(uint32(i)) alen := aggregateDataPerDay(uint32(i))

View File

@ -131,7 +131,7 @@ func checkInterval(days uint32) bool {
func (s *statsCtx) dbOpen() bool { func (s *statsCtx) dbOpen() bool {
var err error var err error
log.Tracef("db.Open...") log.Tracef("db.Open...")
s.db, err = bolt.Open(s.conf.Filename, 0644, nil) s.db, err = bolt.Open(s.conf.Filename, 0o644, nil)
if err != nil { if err != nil {
log.Error("Stats: open DB: %s: %s", s.conf.Filename, err) log.Error("Stats: open DB: %s: %s", s.conf.Filename, err)
if err.Error() == "invalid argument" { if err.Error() == "invalid argument" {
@ -274,10 +274,7 @@ func convertMapToArray(m map[string]uint64, max int) []countPair {
a = append(a, pair) a = append(a, pair)
} }
less := func(i, j int) bool { less := func(i, j int) bool {
if a[i].Count >= a[j].Count { return a[j].Count < a[i].Count
return true
}
return false
} }
sort.Slice(a, less) sort.Slice(a, less)
if max > len(a) { if max > len(a) {
@ -297,15 +294,17 @@ func convertArrayToMap(a []countPair) map[string]uint64 {
func serialize(u *unit) *unitDB { func serialize(u *unit) *unitDB {
udb := unitDB{} udb := unitDB{}
udb.NTotal = u.nTotal udb.NTotal = u.nTotal
for _, it := range u.nResult {
udb.NResult = append(udb.NResult, it) udb.NResult = append(udb.NResult, u.nResult...)
}
if u.nTotal != 0 { if u.nTotal != 0 {
udb.TimeAvg = uint32(u.timeSum / u.nTotal) udb.TimeAvg = uint32(u.timeSum / u.nTotal)
} }
udb.Domains = convertMapToArray(u.domains, maxDomains) udb.Domains = convertMapToArray(u.domains, maxDomains)
udb.BlockedDomains = convertMapToArray(u.blockedDomains, maxDomains) udb.BlockedDomains = convertMapToArray(u.blockedDomains, maxDomains)
udb.Clients = convertMapToArray(u.clients, maxClients) udb.Clients = convertMapToArray(u.clients, maxClients)
return &udb return &udb
} }
@ -499,7 +498,8 @@ func (s *statsCtx) loadUnits(limit uint32) ([]*unitDB, uint32) {
curID := s.unit.id curID := s.unit.id
s.unitLock.Unlock() s.unitLock.Unlock()
units := []*unitDB{} //per-hour units // Per-hour units.
units := []*unitDB{}
firstID := curID - limit + 1 firstID := curID - limit + 1
for i := firstID; i != curID; i++ { for i := firstID; i != curID; i++ {
u := s.loadUnitFromDB(tx, i) u := s.loadUnitFromDB(tx, i)

View File

@ -59,7 +59,7 @@ func (a *AutoHosts) Init(hostsFn string) {
a.hostsFn = hostsFn a.hostsFn = hostsFn
} }
if IsOpenWrt() { if IsOpenWRT() {
a.hostsDirs = append(a.hostsDirs, "/tmp/hosts") // OpenWRT: "/tmp/hosts/dhcp.cfg01411c" a.hostsDirs = append(a.hostsDirs, "/tmp/hosts") // OpenWRT: "/tmp/hosts/dhcp.cfg01411c"
} }
@ -106,8 +106,8 @@ func (a *AutoHosts) Close() {
} }
} }
// Process - get the list of IP addresses for the hostname // Process returns the list of IP addresses for the hostname or nil if nothing
// Return nil if not found // found.
func (a *AutoHosts) Process(host string, qtype uint16) []net.IP { func (a *AutoHosts) Process(host string, qtype uint16) []net.IP {
if qtype == dns.TypePTR { if qtype == dns.TypePTR {
return nil return nil
@ -115,11 +115,12 @@ func (a *AutoHosts) Process(host string, qtype uint16) []net.IP {
var ipsCopy []net.IP var ipsCopy []net.IP
a.lock.Lock() a.lock.Lock()
ips, _ := a.table[host]
if len(ips) != 0 { if ips, ok := a.table[host]; ok {
ipsCopy = make([]net.IP, len(ips)) ipsCopy = make([]net.IP, len(ips))
copy(ipsCopy, ips) copy(ipsCopy, ips)
} }
a.lock.Unlock() a.lock.Unlock()
log.Debug("AutoHosts: answer: %s -> %v", host, ipsCopy) log.Debug("AutoHosts: answer: %s -> %v", host, ipsCopy)
@ -256,18 +257,16 @@ func (a *AutoHosts) load(table map[string][]net.IP, tableRev map[string]string,
func (a *AutoHosts) watcherLoop() { func (a *AutoHosts) watcherLoop() {
for { for {
select { select {
case event, ok := <-a.watcher.Events: case event, ok := <-a.watcher.Events:
if !ok { if !ok {
return return
} }
// skip duplicate events
repeat := true repeat := true
for repeat { for repeat {
select { select {
case _ = <-a.watcher.Events: case <-a.watcher.Events:
// skip this event // Skip this duplicating event
default: default:
repeat = false repeat = false
} }
@ -292,18 +291,15 @@ func (a *AutoHosts) watcherLoop() {
} }
} }
// updateLoop - read static hosts from system files // updateLoop reads static hosts from system files.
func (a *AutoHosts) updateLoop() { func (a *AutoHosts) updateLoop() {
for { for ok := range a.updateChan {
select { if !ok {
case ok := <-a.updateChan: log.Debug("Finished AutoHosts update loop")
if !ok { return
log.Debug("Finished AutoHosts update loop")
return
}
a.updateHosts()
} }
a.updateHosts()
} }
} }

View File

@ -10,26 +10,23 @@ import (
"strings" "strings"
) )
// ContainsString checks if "v" is in the array "arr" // ContainsString checks if string is in the slice of strings.
func ContainsString(arr []string, v string) bool { func ContainsString(strs []string, str string) bool {
for _, i := range arr { for _, s := range strs {
if i == v { if s == str {
return true return true
} }
} }
return false return false
} }
// fileExists returns TRUE if file exists // FileExists returns true if file exists.
func FileExists(fn string) bool { func FileExists(fn string) bool {
_, err := os.Stat(fn) _, err := os.Stat(fn)
if err != nil { return err == nil
return false
}
return true
} }
// runCommand runs shell command // RunCommand runs shell command.
func RunCommand(command string, arguments ...string) (int, string, error) { func RunCommand(command string, arguments ...string) (int, string, error) {
cmd := exec.Command(command, arguments...) cmd := exec.Command(command, arguments...)
out, err := cmd.Output() out, err := cmd.Output()
@ -71,16 +68,8 @@ func SplitNext(str *string, splitBy byte) string {
return strings.TrimSpace(s) return strings.TrimSpace(s)
} }
// MinInt - return the minimum value // IsOpenWRT checks if OS is OpenWRT.
func MinInt(a, b int) int { func IsOpenWRT() bool {
if a < b {
return a
}
return b
}
// IsOpenWrt checks if OS is OpenWRT
func IsOpenWrt() bool {
if runtime.GOOS != "linux" { if runtime.GOOS != "linux" {
return false return false
} }
@ -92,12 +81,3 @@ func IsOpenWrt() bool {
return strings.Contains(string(body), "OpenWrt") return strings.Contains(string(body), "OpenWrt")
} }
// IsFreeBSD checks if OS is FreeBSD
func IsFreeBSD() bool {
if runtime.GOOS == "freebsd" {
return true
}
return false
}