From cd4e879b9b39e41ced4af9716fa5e5cbe0c202ff Mon Sep 17 00:00:00 2001 From: Mikhail Knyazhev Date: Sun, 29 Sep 2024 03:19:30 +0300 Subject: [PATCH] fix xdns --- go.mod | 2 +- go.sum | 4 +- internal/commands/setup.go | 292 +++++++++---------------------------- xdns/client.go | 14 +- xdns/common.go | 4 +- xdns/server.go | 29 ++-- xdns/zone_resolver.go | 12 +- 7 files changed, 88 insertions(+), 269 deletions(-) diff --git a/go.mod b/go.mod index 6197295..d555d5a 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( go.osspkg.com/errors v0.3.1 go.osspkg.com/events v0.3.0 go.osspkg.com/grape v1.2.0 - go.osspkg.com/ioutils v0.4.6 + go.osspkg.com/ioutils v0.4.7 go.osspkg.com/logx v0.4.1 go.osspkg.com/network v0.4.2 go.osspkg.com/random v0.3.1 diff --git a/go.sum b/go.sum index ef4035e..a0781ad 100644 --- a/go.sum +++ b/go.sum @@ -134,8 +134,8 @@ go.osspkg.com/events v0.3.0 h1:W2IngTsKs0BKYIglqhrETwtpo6uNSZXWRIt0/l7c6dY= go.osspkg.com/events v0.3.0/go.mod h1:Cjpx+qNM1y2MIAygFyZWYagTuRiYirmKppZQdaZumd4= go.osspkg.com/grape v1.2.0 h1:4t/AadlqH7kkoUFVn3u65RqOCaYQOHmkiuCulauWeAE= go.osspkg.com/grape v1.2.0/go.mod h1:/BpreooYFHz+VdKei4ANaYdxl0qcPXU9amT0MODg17c= -go.osspkg.com/ioutils v0.4.6 h1:gnfUf6H0NaJNStmI6/TQ+LkfrkF2aYx3nSyeeGbqxJQ= -go.osspkg.com/ioutils v0.4.6/go.mod h1:58HhG2NHf9JUtixAH3R2XISlUmJruwVIUZ3039QVjOY= +go.osspkg.com/ioutils v0.4.7 h1:ERr37BhApkVH34Ebq2yPY+50p38bElSns6pX64wVsyw= +go.osspkg.com/ioutils v0.4.7/go.mod h1:58HhG2NHf9JUtixAH3R2XISlUmJruwVIUZ3039QVjOY= go.osspkg.com/logx v0.4.1 h1:EAzp6EfUmx3YurJrIO2heXIGLimi/RwlnxbM8Lpe8jY= go.osspkg.com/logx v0.4.1/go.mod h1:hz0oh9mu6Wo4+K6Yk59EbqYVj504FWqSDhEi71btM5g= go.osspkg.com/network v0.4.2 h1:mRJLcXu6KSKX2GkB3lPdL+aZl4vciHnm7W6j4vR6F3E= diff --git a/internal/commands/setup.go b/internal/commands/setup.go index 2bf796d..558cb1c 100644 --- a/internal/commands/setup.go +++ b/internal/commands/setup.go @@ -221,182 +221,89 @@ var ciConfigs = map[string]string{ } var golangciLintConfig = ` -# options for analysis running run: - # timeout for analysis, e.g. 30s, 5m, default is 1m - deadline: 5m - - # exit code when at least one issue was found, default is 1 + go: "1.22.5" + concurrency: 4 + timeout: 5m + tests: false issues-exit-code: 1 - - # include test files or not, default is true - tests: true - - # 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: - - easyjson + modules-download-mode: readonly issues: - # Independently from option 'exclude' we use default exclude patterns, - # it can be disabled by this option. To list all - # excluded by default patterns execute 'golangci-lint run --help'. - # Default value for this option is true. exclude-use-default: false - # Excluding configuration per-path, per-linter, per-text and per-source - exclude-rules: - # Exclude some linters from running on tests files. - - path: _test\.go - linters: - - prealloc - - errcheck - -# output configuration options -output: - # colored-line-number|line-number|json|tab|checkstyle, default is "colored-line-number" - format: colored-line-number + max-issues-per-linter: 100 + max-same-issues: 4 + new: false + exclude-files: + - ".+_test.go" + exclude-dirs: + - "vendor$" - # print lines of code with issue, default is true - print-issued-lines: true - - # print linter name in the end of issue text, default is true - print-linter-name: true +output: + formats: + - format: line-number + sort-results: true -# all available settings of specific linters linters-settings: govet: - # report about shadowed variables check-shadowing: true - enable: - # report mismatches between assembly files and Go declarations - - asmdecl - # check for useless assignments - - assign - # check for common mistakes using the sync/atomic package - - atomic - # check for non-64-bits-aligned arguments to sync/atomic functions - - atomicalign - # check for common mistakes involving boolean operators - - bools - # check that +build tags are well-formed and correctly located - - buildtag - # detect some violations of the cgo pointer passing rules - - cgocall - # check for unkeyed composite literals - - composites - # check for locks erroneously passed by value - - copylocks - # check for calls of reflect.DeepEqual on error values - - deepequalerrors - # report passing non-pointer or non-error values to errors.As - - errorsas - # find calls to a particular function - - findcall - # report assembly that clobbers the frame pointer before saving it - - framepointer - # check for mistakes using HTTP responses - - httpresponse - # detect impossible interface-to-interface type assertions - - ifaceassert - # check references to loop variables from within nested functions - - loopclosure - # check cancel func returned by context.WithCancel is called - - lostcancel - # check for useless comparisons between functions and nil - - nilfunc - # check for redundant or impossible nil comparisons - - nilness - # check consistency of Printf format strings and arguments - - printf - # check for comparing reflect.Value values with == or reflect.DeepEqual - - reflectvaluecompare - # check for possible unintended shadowing of variables - - shadow - # check for shifts that equal or exceed the width of the integer - - shift - # check for unbuffered channel of os.Signal - - sigchanyzer - # check the argument type of sort.Slice - - sortslice - # check signature of methods of well-known interfaces - - stdmethods - # check for string(int) conversions - - stringintconv - # check that struct field tags conform to reflect.StructTag.Get - - structtag - # report calls to (*testing.T).Fatal from goroutines started by a test. - - testinggoroutine - # check for common mistaken usages of tests and examples - - tests - # report passing non-pointer or non-interface values to unmarshal - - unmarshal - # check for unreachable code - - unreachable - # check for invalid conversions of uintptr to unsafe.Pointer - - unsafeptr - # check for unused results of calls to some functions - - unusedresult - # checks for unused writes - - unusedwrite - disable: - # find structs that would use less memory if their fields were sorted - - fieldalignment + enable: + - asmdecl + - assign + - atomic + - atomicalign + - bools + - buildtag + - cgocall + - composites + - copylocks + - deepequalerrors + - errorsas + - findcall + - framepointer + - httpresponse + - ifaceassert + - loopclosure + - lostcancel + - nilfunc + - nilness + - printf + - reflectvaluecompare + - shadow + - shift + - sigchanyzer + - sortslice + - stdmethods + - stringintconv + - structtag + - testinggoroutine + - tests + - unmarshal + - unreachable + - unsafeptr + - unusedresult + - unusedwrite + disable: + - fieldalignment gofmt: - # simplify code: gofmt with '-s' option, true by default simplify: true errcheck: - # report about not checking of errors in type assetions: 'a := b.(MyStruct)'; - # default is false: such cases aren't reported by default. check-type-assertions: true - # report about assignment of errors to blank identifier: 'num, _ := strconv.Atoi(numStr)'; - # default is false: such cases aren't reported by default. check-blank: true gocyclo: - # minimal code complexity to report, 30 by default (but we recommend 10-20) - min-complexity: 15 + min-complexity: 30 misspell: - # Correct spellings using locale preferences for US or UK. - # Default is to use a neutral variety of English. - # Setting locale to US will correct the British spelling of 'colour' to 'color'. locale: US prealloc: - # XXX: we don't recommend using this linter before doing performance profiling. - # For most programs usage of prealloc will be a premature optimization. - # Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them. - # True by default. simple: true - range-loops: true # Report preallocation suggestions on range loops, true by default - for-loops: true # Report preallocation suggestions on for loops, false by default + range-loops: true + for-loops: true unparam: - # Inspect exported functions, default is false. Set to true if no external program/library imports your code. - # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors: - # if it's called for subdir of a project it can't find external interfaces. All text editor integrations - # with golangci-lint call it on a directory with the changed file. check-exported: false gci: - # Section configuration to compare against. - # Section names are case-insensitive and may contain parameters in (). - # The default order of sections is 'standard > default > custom > blank > dot', - # If 'custom-order' is 'true', it follows the order of 'sections' option. - # Default: ["standard", "default"] - #sections: - #- standard # Standard section: captures all standard packages. - #- default # Default section: contains all imports that could not be matched to another section type. - #- blank # Blank section: contains all blank imports. This section is not present unless explicitly enabled. - #- dot # Dot section: contains all dot imports. This section is not present unless explicitly enabled. - # Skip generated files. - # Default: true skip-generated: true - # Enable custom order of sections. - # If 'true', make the section order the same as the order of 'sections'. - # Default: false custom-order: false gosec: - # To select a subset of rules to run. - # Available rules: https://github.com/securego/gosec#available-rules - # Default: [] - means include all rules includes: - G101 # Look for hard coded credentials - G102 # Bind to all interfaces @@ -432,9 +339,6 @@ linters-settings: - G504 # Import blocklist: net/http/cgi - G505 # Import blocklist: crypto/sha1 - G601 # Implicit memory aliasing of items from a range statement - # To specify a set of rules to explicitly exclude. - # Available rules: https://github.com/securego/gosec#available-rules - # Default: [] excludes: - G101 # Look for hard coded credentials - G102 # Bind to all interfaces @@ -470,104 +374,39 @@ linters-settings: - G504 # Import blocklist: net/http/cgi - G505 # Import blocklist: crypto/sha1 - G601 # Implicit memory aliasing of items from a range statement - # Exclude generated files - # Default: false exclude-generated: true - # Filter out the issues with a lower severity than the given value. - # Valid options are: low, medium, high. - # Default: low severity: medium - # Filter out the issues with a lower confidence than the given value. - # Valid options are: low, medium, high. - # Default: low confidence: medium - # Concurrency value. - # Default: the number of logical CPUs usable by the current process. concurrency: 12 - # To specify the configuration of rules. config: - # Globals are applicable to all rules. global: - # If true, ignore #nosec in comments (and an alternative as well). - # Default: false nosec: true - # Add an alternative comment prefix to #nosec (both will work at the same time). - # Default: "" "#nosec": "#my-custom-nosec" - # Define whether nosec issues are counted as finding or not. - # Default: false show-ignored: true - # Audit mode enables addition checks that for normal code analysis might be too nosy. - # Default: false audit: true G101: - # Regexp pattern for variables and constants to find. - # Default: "(?i)passwd|pass|password|pwd|secret|token|pw|apiKey|bearer|cred" - pattern: "(?i)example" - # If true, complain about all cases (even with low entropy). - # Default: false + pattern: "(?i)passwd|pass|password|pwd|secret|token|pw|apiKey|bearer|cred" ignore_entropy: false - # Maximum allowed entropy of the string. - # Default: "80.0" entropy_threshold: "80.0" - # Maximum allowed value of entropy/string length. - # Is taken into account if entropy >= entropy_threshold/2. - # Default: "3.0" per_char_threshold: "3.0" - # Calculate entropy for first N chars of the string. - # Default: "16" truncate: "32" - # Additional functions to ignore while checking unhandled errors. - # Following functions always ignored: - # bytes.Buffer: - # - Write - # - WriteByte - # - WriteRune - # - WriteString - # fmt: - # - Print - # - Printf - # - Println - # - Fprint - # - Fprintf - # - Fprintln - # strings.Builder: - # - Write - # - WriteByte - # - WriteRune - # - WriteString - # io.PipeWriter: - # - CloseWithError - # hash.Hash: - # - Write - # os: - # - Unsetenv - # Default: {} G104: fmt: - Fscanf G111: - # Regexp pattern to find potential directory traversal. - # Default: "http\\.Dir\\(\"\\/\"\\)|http\\.Dir\\('\\/'\\)" - pattern: "custom\\.Dir\\(\\)" - # Maximum allowed permissions mode for os.Mkdir and os.MkdirAll - # Default: "0750" + pattern: "http\\.Dir\\(\"\\/\"\\)|http\\.Dir\\('\\/'\\)" G301: "0750" - # Maximum allowed permissions mode for os.OpenFile and os.Chmod - # Default: "0600" G302: "0600" - # Maximum allowed permissions mode for os.WriteFile and ioutil.WriteFile - # Default: "0600" G306: "0600" lll: - # Max line length, lines longer will be reported. - # '\t' is counted as 1 character by default, and can be changed with the tab-width option. - # Default: 120. - line-length: 120 - # Tab width in spaces. - # Default: 1 + line-length: 130 tab-width: 1 + staticcheck: + go: "1.15" + # SAxxxx checks in https://staticcheck.io/docs/configuration/options/#checks + # Default: ["*"] + checks: [ "*", "-SA1019" ] linters: disable-all: true @@ -584,7 +423,6 @@ linters: - unused - prealloc - durationcheck - - nolintlint - staticcheck - makezero - nilerr diff --git a/xdns/client.go b/xdns/client.go index 906d46c..40cb396 100644 --- a/xdns/client.go +++ b/xdns/client.go @@ -63,14 +63,12 @@ func (v *Client) SetZoneResolver(r ZoneResolver) { v.resolver = r } -func (v *Client) Exchange(q []dns.Question) ([]dns.RR, error) { +func (v *Client) Exchange(question dns.Question) ([]dns.RR, error) { var errs error - result := make([]dns.RR, 0, len(q)) - - for _, question := range q { - address := v.resolver.Resolve(question.Name) - msg := new(dns.Msg).SetQuestion(question.Name, question.Qtype) + msg := new(dns.Msg).SetQuestion(question.Name, question.Qtype) + ns := v.resolver.Resolve(question.Name) + for _, address := range ns { resp, _, err := v.cli.Exchange(msg, address) if err != nil { errs = errors.Wrap(errs, errors.Wrapf(err, "name: %s, dns: %s", question.String(), address)) @@ -83,8 +81,8 @@ func (v *Client) Exchange(q []dns.Question) ([]dns.RR, error) { continue } - result = append(result, resp.Answer...) + return resp.Answer, nil } - return result, errs + return nil, errs } diff --git a/xdns/common.go b/xdns/common.go index b85be2a..3f6402e 100644 --- a/xdns/common.go +++ b/xdns/common.go @@ -10,9 +10,9 @@ import ( ) type HandlerDNS interface { - Exchange(q []dns.Question) ([]dns.RR, error) + Exchange(q dns.Question) ([]dns.RR, error) } type ZoneResolver interface { - Resolve(name string) string + Resolve(name string) []string } diff --git a/xdns/server.go b/xdns/server.go index c53b03e..582e49c 100644 --- a/xdns/server.go +++ b/xdns/server.go @@ -20,7 +20,6 @@ type Server struct { serv []*dns.Server handler HandlerDNS wg syncing.Group - mux syncing.Lock } func NewServer(conf Config) *Server { @@ -29,7 +28,6 @@ func NewServer(conf Config) *Server { serv: make([]*dns.Server, 0, 2), handler: DefaultExchanger(), wg: syncing.NewGroup(), - mux: syncing.NewLock(), } } @@ -81,9 +79,7 @@ func (v *Server) Down() error { } func (v *Server) HandleFunc(r HandlerDNS) { - v.mux.Lock(func() { - v.handler = r - }) + v.handler = r } func (v *Server) dnsHandler(w dns.ResponseWriter, msg *dns.Msg) { @@ -93,21 +89,16 @@ func (v *Server) dnsHandler(w dns.ResponseWriter, msg *dns.Msg) { response.SetReply(msg) response.SetRcode(msg, dns.RcodeSuccess) - var ( - answer []dns.RR - err error - ) - v.mux.RLock(func() { - answer, err = v.handler.Exchange(msg.Question) - }) - - if err != nil { - logx.Error("DNS handler", "question", msg, "err", err) - } else { - response.Answer = append(response.Answer, answer...) + for _, q := range msg.Question { + answer, err := v.handler.Exchange(q) + if err != nil { + logx.Error("DNS exchange", "question", msg, "err", err) + } else { + response.Answer = append(response.Answer, answer...) + } } - if err = w.WriteMsg(response); err != nil { - logx.Error("DNS handler", "question", msg, "answer", response, "err", err) + if err := w.WriteMsg(response); err != nil { + logx.Error("DNS response", "question", msg, "answer", response, "err", err) } } diff --git a/xdns/zone_resolver.go b/xdns/zone_resolver.go index 592f842..2774b6d 100644 --- a/xdns/zone_resolver.go +++ b/xdns/zone_resolver.go @@ -6,14 +6,9 @@ package xdns import ( - "math/rand" - "time" - "go.osspkg.com/network/address" ) -var rnd = rand.New(rand.NewSource(time.Now().UnixNano())) - type ZoneResolve struct { dns []string } @@ -26,11 +21,8 @@ func NewSimpleZoneResolve(dns ...string) *ZoneResolve { return &ZoneResolve{dns: ndns} } -func (v *ZoneResolve) Resolve(name string) string { - if len(v.dns) == 1 { - return v.dns[0] - } - return v.dns[rnd.Intn(len(v.dns))] +func (v *ZoneResolve) Resolve(name string) []string { + return append(make([]string, 0, len(v.dns)), v.dns...) } func DefaultExchanger(dns ...string) HandlerDNS {