Added golangci-lint configuration and prepared for the integrattion

This commit is contained in:
Andrey Meshkov 2019-01-25 16:01:27 +03:00 committed by Eugene Bujak
parent 69a75fbcaa
commit ec6b1f7c42
13 changed files with 108 additions and 42 deletions

55
.golangci.yml Normal file
View File

@ -0,0 +1,55 @@
# options for analysis running
run:
# default concurrency is a available CPU number
concurrency: 4
# timeout for analysis, e.g. 30s, 5m, default is 1m
deadline: 2m
# which files to skip: they will be analyzed, but issues from them
# won't be reported. Default value is empty list, but there is
# no need to include all autogenerated files, we confidently recognize
# autogenerated files. If it's not please let us know.
skip-files:
- ".*generated.*"
- dnsfilter/rule_to_regexp.go
# all available settings of specific linters
linters-settings:
errcheck:
# [deprecated] comma-separated list of pairs of the form pkg:regex
# the regex is used to ignore names within pkg. (default "fmt:.*").
# see https://github.com/kisielk/errcheck#the-deprecated-method for details
ignore: fmt:.*,net:SetReadDeadline,net/http:^Write
gocyclo:
min-complexity: 20
lll:
line-length: 200
linters:
enable-all: true
disable:
- interfacer
- gocritic
- scopelint
- gochecknoglobals
- gochecknoinits
- prealloc
- maligned
- goconst # disabled until it's possible to configure
fast: true
issues:
# List of regexps of issue texts to exclude, empty list by default.
# But independently from this option we use default exclude patterns,
# it can be disabled by `exclude-use-default: false`. To list all
# excluded by default patterns execute `golangci-lint run --help`
exclude:
# structcheck cannot detect usages while they're there
- .parentalServer. is unused
- .safeBrowsingServer. is unused
# errcheck
- Error return value of .s.closeConn. is not checked
# goconst
- string .forcesafesearch.google.com. has 3 occurrences

View File

@ -10,7 +10,7 @@ import (
"github.com/AdguardTeam/AdGuardHome/dnsfilter" "github.com/AdguardTeam/AdGuardHome/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/dnsforward" "github.com/AdguardTeam/AdGuardHome/dnsforward"
"github.com/hmage/golibs/log" "github.com/hmage/golibs/log"
"gopkg.in/yaml.v2" yaml "gopkg.in/yaml.v2"
) )
const ( const (

View File

@ -15,7 +15,7 @@ import (
"github.com/AdguardTeam/dnsproxy/upstream" "github.com/AdguardTeam/dnsproxy/upstream"
"github.com/hmage/golibs/log" "github.com/hmage/golibs/log"
"github.com/miekg/dns" "github.com/miekg/dns"
"gopkg.in/asaskevich/govalidator.v4" govalidator "gopkg.in/asaskevich/govalidator.v4"
) )
const updatePeriod = time.Minute * 30 const updatePeriod = time.Minute * 30
@ -321,27 +321,27 @@ func handleFilteringStatus(w http.ResponseWriter, r *http.Request) {
} }
func handleFilteringAddURL(w http.ResponseWriter, r *http.Request) { func handleFilteringAddURL(w http.ResponseWriter, r *http.Request) {
filter := filter{} f := filter{}
err := json.NewDecoder(r.Body).Decode(&filter) err := json.NewDecoder(r.Body).Decode(&f)
if err != nil { if err != nil {
httpError(w, http.StatusBadRequest, "Failed to parse request body json: %s", err) httpError(w, http.StatusBadRequest, "Failed to parse request body json: %s", err)
return return
} }
if len(filter.URL) == 0 { if len(f.URL) == 0 {
http.Error(w, "URL parameter was not specified", 400) http.Error(w, "URL parameter was not specified", 400)
return return
} }
if valid := govalidator.IsRequestURL(filter.URL); !valid { if valid := govalidator.IsRequestURL(f.URL); !valid {
http.Error(w, "URL parameter is not valid request URL", 400) http.Error(w, "URL parameter is not valid request URL", 400)
return return
} }
// Check for duplicates // Check for duplicates
for i := range config.Filters { for i := range config.Filters {
if config.Filters[i].URL == filter.URL { if config.Filters[i].URL == f.URL {
errorText := fmt.Sprintf("Filter URL already added -- %s", filter.URL) errorText := fmt.Sprintf("Filter URL already added -- %s", f.URL)
log.Println(errorText) log.Println(errorText)
http.Error(w, errorText, http.StatusBadRequest) http.Error(w, errorText, http.StatusBadRequest)
return return
@ -349,34 +349,34 @@ func handleFilteringAddURL(w http.ResponseWriter, r *http.Request) {
} }
// Set necessary properties // Set necessary properties
filter.ID = assignUniqueFilterID() f.ID = assignUniqueFilterID()
filter.Enabled = true f.Enabled = true
// Download the filter contents // Download the filter contents
ok, err := filter.update(true) ok, err := f.update(true)
if err != nil { if err != nil {
errorText := fmt.Sprintf("Couldn't fetch filter from url %s: %s", filter.URL, err) errorText := fmt.Sprintf("Couldn't fetch filter from url %s: %s", f.URL, err)
log.Println(errorText) log.Println(errorText)
http.Error(w, errorText, http.StatusBadRequest) http.Error(w, errorText, http.StatusBadRequest)
return return
} }
if filter.RulesCount == 0 { if f.RulesCount == 0 {
errorText := fmt.Sprintf("Filter at the url %s has no rules (maybe it points to blank page?)", filter.URL) errorText := fmt.Sprintf("Filter at the url %s has no rules (maybe it points to blank page?)", f.URL)
log.Println(errorText) log.Println(errorText)
http.Error(w, errorText, http.StatusBadRequest) http.Error(w, errorText, http.StatusBadRequest)
return return
} }
if !ok { if !ok {
errorText := fmt.Sprintf("Filter at the url %s is invalid (maybe it points to blank page?)", filter.URL) errorText := fmt.Sprintf("Filter at the url %s is invalid (maybe it points to blank page?)", f.URL)
log.Println(errorText) log.Println(errorText)
http.Error(w, errorText, http.StatusBadRequest) http.Error(w, errorText, http.StatusBadRequest)
return return
} }
// Save the filter contents // Save the filter contents
err = filter.save() err = f.save()
if err != nil { if err != nil {
errorText := fmt.Sprintf("Failed to save filter %d due to %s", filter.ID, err) errorText := fmt.Sprintf("Failed to save filter %d due to %s", f.ID, err)
log.Println(errorText) log.Println(errorText)
http.Error(w, errorText, http.StatusBadRequest) http.Error(w, errorText, http.StatusBadRequest)
return return
@ -384,7 +384,7 @@ func handleFilteringAddURL(w http.ResponseWriter, r *http.Request) {
// URL is deemed valid, append it to filters, update config, write new filter file and tell dns to reload it // URL is deemed valid, append it to filters, update config, write new filter file and tell dns to reload it
// TODO: since we directly feed filters in-memory, revisit if writing configs is always necessary // TODO: since we directly feed filters in-memory, revisit if writing configs is always necessary
config.Filters = append(config.Filters, filter) config.Filters = append(config.Filters, f)
err = writeAllConfigs() err = writeAllConfigs()
if err != nil { if err != nil {
errorText := fmt.Sprintf("Couldn't write config file: %s", err) errorText := fmt.Sprintf("Couldn't write config file: %s", err)
@ -393,9 +393,14 @@ func handleFilteringAddURL(w http.ResponseWriter, r *http.Request) {
return return
} }
reconfigureDNSServer() err = reconfigureDNSServer()
if err != nil {
errorText := fmt.Sprintf("Couldn't reconfigure the DNS server: %s", err)
log.Println(errorText)
http.Error(w, errorText, http.StatusInternalServerError)
}
_, err = fmt.Fprintf(w, "OK %d rules\n", filter.RulesCount) _, err = fmt.Fprintf(w, "OK %d rules\n", f.RulesCount)
if err != nil { if err != nil {
errorText := fmt.Sprintf("Couldn't write body: %s", err) errorText := fmt.Sprintf("Couldn't write body: %s", err)
log.Println(errorText) log.Println(errorText)

View File

@ -101,9 +101,9 @@ func handleDHCPInterfaces(w http.ResponseWriter, r *http.Request) {
MTU: ifaces[i].MTU, MTU: ifaces[i].MTU,
HardwareAddr: ifaces[i].HardwareAddr.String(), HardwareAddr: ifaces[i].HardwareAddr.String(),
} }
addrs, err := ifaces[i].Addrs() addrs, errAddrs := ifaces[i].Addrs()
if err != nil { if errAddrs != nil {
httpError(w, http.StatusInternalServerError, "Failed to get addresses for interface %v: %s", ifaces[i].Name, err) httpError(w, http.StatusInternalServerError, "Failed to get addresses for interface %v: %s", ifaces[i].Name, errAddrs)
return return
} }
for _, addr := range addrs { for _, addr := range addrs {
@ -155,7 +155,7 @@ func handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Request) {
} }
func startDHCPServer() error { func startDHCPServer() error {
if config.DHCP.Enabled == false { if !config.DHCP.Enabled {
// not enabled, don't do anything // not enabled, don't do anything
return nil return nil
} }

View File

@ -59,7 +59,7 @@ func CheckIfOtherDHCPServersPresent(ifaceName string) (bool, error) {
maxUDPsizeRaw := make([]byte, 2) maxUDPsizeRaw := make([]byte, 2)
binary.BigEndian.PutUint16(maxUDPsizeRaw, 1500) binary.BigEndian.PutUint16(maxUDPsizeRaw, 1500)
leaseTimeRaw := make([]byte, 4) leaseTimeRaw := make([]byte, 4)
leaseTime := uint32(math.RoundToEven(time.Duration(time.Hour * 24 * 90).Seconds())) leaseTime := uint32(math.RoundToEven((time.Hour * 24 * 90).Seconds()))
binary.BigEndian.PutUint32(leaseTimeRaw, leaseTime) binary.BigEndian.PutUint32(leaseTimeRaw, leaseTime)
options := []dhcp4.Option{ options := []dhcp4.Option{
{Code: dhcp4.OptionParameterRequestList, Value: requestList}, {Code: dhcp4.OptionParameterRequestList, Value: requestList},

View File

@ -83,6 +83,7 @@ func (s *Server) Start(config *ServerConfig) error {
s.leaseStart, err = parseIPv4(s.RangeStart) s.leaseStart, err = parseIPv4(s.RangeStart)
if err != nil { if err != nil {
s.closeConn() // in case it was already started s.closeConn() // in case it was already started
return wrapErrPrint(err, "Failed to parse range start address %s", s.RangeStart) return wrapErrPrint(err, "Failed to parse range start address %s", s.RangeStart)
} }
@ -178,7 +179,7 @@ func (s *Server) reserveLease(p dhcp4.Packet) (*Lease, error) {
} }
// not assigned a lease, create new one, find IP from LRU // not assigned a lease, create new one, find IP from LRU
log.Tracef("Lease not found for %s: creating new one", hwaddr) log.Tracef("Lease not found for %s: creating new one", hwaddr)
ip, err := s.findFreeIP(p, hwaddr) ip, err := s.findFreeIP(hwaddr)
if err != nil { if err != nil {
return nil, wrapErrPrint(err, "Couldn't find free IP for the lease %s", hwaddr.String()) return nil, wrapErrPrint(err, "Couldn't find free IP for the lease %s", hwaddr.String())
} }
@ -202,7 +203,7 @@ func (s *Server) locateLease(p dhcp4.Packet) *Lease {
return nil return nil
} }
func (s *Server) findFreeIP(p dhcp4.Packet, hwaddr net.HardwareAddr) (net.IP, error) { func (s *Server) findFreeIP(hwaddr net.HardwareAddr) (net.IP, error) {
// if IP pool is nil, lazy initialize it // if IP pool is nil, lazy initialize it
if s.IPpool == nil { if s.IPpool == nil {
s.IPpool = make(map[[4]byte]net.HardwareAddr) s.IPpool = make(map[[4]byte]net.HardwareAddr)
@ -227,7 +228,7 @@ func (s *Server) findFreeIP(p dhcp4.Packet, hwaddr net.HardwareAddr) (net.IP, er
if foundIP == nil { if foundIP == nil {
// TODO: LRU // TODO: LRU
return nil, fmt.Errorf("Couldn't find free entry in IP pool") return nil, fmt.Errorf("couldn't find free entry in IP pool")
} }
s.reserveIP(foundIP, hwaddr) s.reserveIP(foundIP, hwaddr)
@ -281,7 +282,7 @@ func (s *Server) ServeDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options dh
case dhcp4.Request: // Broadcast From Client - I'll take that IP (Also start for renewals) case dhcp4.Request: // Broadcast From Client - I'll take that IP (Also start for renewals)
// start/renew a lease -- update lease time // start/renew a lease -- update lease time
// some clients (OSX) just go right ahead and do Request first from previously known IP, if they get NAK, they restart full cycle with Discover then Request // some clients (OSX) just go right ahead and do Request first from previously known IP, if they get NAK, they restart full cycle with Discover then Request
return s.handleDHCP4Request(p, msgType, options) return s.handleDHCP4Request(p, options)
case dhcp4.Decline: // Broadcast From Client - Sorry I can't use that IP case dhcp4.Decline: // Broadcast From Client - Sorry I can't use that IP
log.Tracef("Got from client: Decline") log.Tracef("Got from client: Decline")
@ -306,7 +307,7 @@ func (s *Server) ServeDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options dh
return nil return nil
} }
func (s *Server) handleDHCP4Request(p dhcp4.Packet, msgType dhcp4.MessageType, options dhcp4.Options) dhcp4.Packet { func (s *Server) handleDHCP4Request(p dhcp4.Packet, options dhcp4.Options) dhcp4.Packet {
log.Tracef("Got from client: Request") log.Tracef("Got from client: Request")
if server, ok := options[dhcp4.OptionServerIdentifier]; ok && !net.IP(server).Equal(s.ipnet.IP) { if server, ok := options[dhcp4.OptionServerIdentifier]; ok && !net.IP(server).Equal(s.ipnet.IP) {
log.Tracef("Request message not for this DHCP server (%v vs %v)", server, s.ipnet.IP) log.Tracef("Request message not for this DHCP server (%v vs %v)", server, s.ipnet.IP)
@ -315,7 +316,7 @@ func (s *Server) handleDHCP4Request(p dhcp4.Packet, msgType dhcp4.MessageType, o
reqIP := net.IP(options[dhcp4.OptionRequestedIPAddress]) reqIP := net.IP(options[dhcp4.OptionRequestedIPAddress])
if reqIP == nil { if reqIP == nil {
reqIP = net.IP(p.CIAddr()) reqIP = p.CIAddr()
} }
if reqIP.To4() == nil { if reqIP.To4() == nil {

View File

@ -76,9 +76,9 @@ func main() {
panic(err) panic(err)
} }
log.Printf("Now serving DHCP") log.Printf("Now serving DHCP")
signal_channel := make(chan os.Signal) signalChannel := make(chan os.Signal)
signal.Notify(signal_channel, syscall.SIGINT, syscall.SIGTERM) signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM)
<-signal_channel <-signalChannel
} }

2
dns.go
View File

@ -52,7 +52,7 @@ func generateServerConfig() dnsforward.ServerConfig {
func startDNSServer() error { func startDNSServer() error {
if isRunning() { if isRunning() {
return fmt.Errorf("Unable to start forwarding DNS server: Already running") return fmt.Errorf("unable to start forwarding DNS server: Already running")
} }
newconfig := generateServerConfig() newconfig := generateServerConfig()

View File

@ -869,7 +869,7 @@ func BenchmarkLotsOfRulesLotsOfHosts(b *testing.B) {
for n := 0; n < b.N; n++ { for n := 0; n < b.N; n++ {
havedata := scanner.Scan() havedata := scanner.Scan()
if !havedata { if !havedata {
hostnames.Seek(0, 0) _, _ = hostnames.Seek(0, 0)
scanner = bufio.NewScanner(hostnames) scanner = bufio.NewScanner(hostnames)
havedata = scanner.Scan() havedata = scanner.Scan()
} }
@ -906,7 +906,7 @@ func BenchmarkLotsOfRulesLotsOfHostsParallel(b *testing.B) {
for pb.Next() { for pb.Next() {
havedata := scanner.Scan() havedata := scanner.Scan()
if !havedata { if !havedata {
hostnames.Seek(0, 0) _, _ = hostnames.Seek(0, 0)
scanner = bufio.NewScanner(hostnames) scanner = bufio.NewScanner(hostnames)
havedata = scanner.Scan() havedata = scanner.Scan()
} }

View File

@ -108,7 +108,12 @@ func logRequest(question *dns.Msg, answer *dns.Msg, result *dnsfilter.Result, el
if len(flushBuffer) > 0 { if len(flushBuffer) > 0 {
// write to file // write to file
// do it in separate goroutine -- we are stalling DNS response this whole time // do it in separate goroutine -- we are stalling DNS response this whole time
go flushToFile(flushBuffer) go func() {
err := flushToFile(flushBuffer)
if err != nil {
log.Printf("Failed to flush the query log: %s", err)
}
}()
} }
} }

View File

@ -340,11 +340,11 @@ func HandleStatsHistory(w http.ResponseWriter, r *http.Request) {
// check if start and time times are within supported time range // check if start and time times are within supported time range
timeRange := timeUnit * statsHistoryElements timeRange := timeUnit * statsHistoryElements
if startTime.Add(timeRange).Before(now) { if startTime.Add(timeRange).Before(now) {
http.Error(w, "start_time parameter is outside of supported range", 501) http.Error(w, "start_time parameter is outside of supported range", http.StatusBadRequest)
return return
} }
if endTime.Add(timeRange).Before(now) { if endTime.Add(timeRange).Before(now) {
http.Error(w, "end_time parameter is outside of supported range", 501) http.Error(w, "end_time parameter is outside of supported range", http.StatusBadRequest)
return return
} }

View File

@ -39,7 +39,7 @@ func safeWriteFile(path string, data []byte) error {
func ensure(method string, handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) { func ensure(method string, 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.Method != method { if r.Method != method {
http.Error(w, "This request must be "+method, 405) http.Error(w, "This request must be "+method, http.StatusMethodNotAllowed)
return return
} }
handler(w, r) handler(w, r)

View File

@ -7,7 +7,7 @@ import (
"path/filepath" "path/filepath"
"github.com/hmage/golibs/log" "github.com/hmage/golibs/log"
"gopkg.in/yaml.v2" yaml "gopkg.in/yaml.v2"
) )
const currentSchemaVersion = 2 // used for upgrading from old configs to new config const currentSchemaVersion = 2 // used for upgrading from old configs to new config