feat: add preliminary message tinkering
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing

Is this the right way to do it? Probably not.
Do I care? No.

Signed-off-by: Sam Therapy <sam@samtherapy.net>
This commit is contained in:
Sam Therapy 2022-09-05 01:36:51 +02:00
parent 068706ae9a
commit bf870e6289
Signed by: sam
GPG key ID: 4D8B07C18F31ACBD
18 changed files with 156 additions and 42 deletions

View file

@ -32,10 +32,11 @@ linters:
- predeclared
- revive
- staticcheck
#- testpackage
- whitespace
- wrapcheck
- wsl
disable:
- structcheck
linters-settings:
govet:

View file

@ -19,7 +19,11 @@ builds:
universal_binaries:
- replace: true
archives:
- replacements:
-
files:
- LICENCE
- completions/**
replacements:
darwin: macOS
linux: Linux
windows: Windows

View file

@ -36,6 +36,8 @@ func ParseCLI(version string) (util.Options, error) {
}
// CLI flags
//
// Remember, when adding a flag edit the manpage and the completions :)
var (
port = flag.Int("port", 0, "`port` to make DNS query (default: 53 for UDP/TCP, 853 for TLS/QUIC)", flag.OptShorthand('p'), flag.OptDisablePrintDefault(true))
query = flag.String("query", "", "domain name to `query` (default: .)", flag.OptShorthand('q'))
@ -51,14 +53,14 @@ func ParseCLI(version string) (util.Options, error) {
edns = flag.Bool("no-edns", false, "disable EDNS entirely")
ednsVer = flag.Uint8("edns-ver", 0, "set EDNS version")
expire = flag.Bool("expire", false, "set EDNS expire")
dnssec = flag.Bool("dnssec", false, "enable DNSSEC", flag.OptShorthand('D'))
expire = flag.Bool("expire", false, "set EDNS expire")
nsid = flag.Bool("nsid", false, "set EDNS NSID", flag.OptShorthand('n'))
cookie = flag.Bool("no-cookie", false, "disable sending EDNS cookie (default: cookie sent)")
tcpKeepAlive = flag.Bool("keep-alive", false, "send EDNS TCP keep-alive")
udpBufSize = flag.Uint16("buffer-size", 1232, "set EDNS UDP buffer size", flag.OptShorthand('b'))
mbzflag = flag.String("zflag", "0", "set EDNS z-flag `value`")
subnet = flag.String("subnet", "", "set EDNS subnet")
subnet = flag.String("subnet", "", "set EDNS client subnet")
padding = flag.Bool("pad", false, "set EDNS padding")
truncate = flag.Bool("no-truncate", false, "ignore truncation if a UDP request truncates (default: retry with TCP)")

View file

@ -84,6 +84,12 @@ func TestMBZ(t *testing.T) { //nolint: paralleltest // Race conditions
func TestInvalidFlag(t *testing.T) { //nolint: paralleltest // Race conditions
old := os.Args
old2 := os.Stdout
old3 := os.Stderr
os.Stdout = os.NewFile(0, os.DevNull)
os.Stderr = os.NewFile(0, os.DevNull)
os.Args = []string{"awl", "--treebug"}
_, err := cli.ParseCLI("TEST")
@ -91,6 +97,8 @@ func TestInvalidFlag(t *testing.T) { //nolint: paralleltest // Race conditions
assert.ErrorContains(t, err, "unknown flag")
os.Args = old
os.Stdout = old2
os.Stderr = old3
}
func TestInvalidDig(t *testing.T) { //nolint: paralleltest // Race conditions
@ -106,13 +114,18 @@ func TestInvalidDig(t *testing.T) { //nolint: paralleltest // Race conditions
func TestVersion(t *testing.T) { //nolint: paralleltest // Race conditions
old := os.Args
old2 := os.Stdout
old3 := os.Stderr
os.Args = []string{"awl", "--version"}
_, err := cli.ParseCLI("TEST")
_, err := cli.ParseCLI("test")
assert.ErrorType(t, err, cli.ErrNotError)
os.Args = old
os.Stdout = old2
os.Stderr = old3
}
func TestTimeout(t *testing.T) { //nolint: paralleltest // Race conditions
@ -154,11 +167,14 @@ func TestRetries(t *testing.T) { //nolint: paralleltest // Race conditions
func FuzzFlags(f *testing.F) {
testcases := []string{"git.froth.zone", "", "!12345", "google.com.edu.org.fr"}
for _, tc := range testcases {
f.Add(tc)
}
f.Fuzz(func(t *testing.T, orig string) {
// Get rid of outputs
old := os.Args
os.Args = []string{"awl", orig}
//nolint:errcheck,gosec // Only make sure the program does not crash

View file

@ -48,8 +48,10 @@ func ParseDig(arg string, opts *util.Options) error {
opts.ShowQuery = isNo
case "ttlunits":
opts.HumanTTL = isNo
case "ttlid":
case "ttl", "ttlid":
opts.ShowTTL = isNo
case "class":
opts.ShowClass = isNo
// EDNS queries
case "dnssec":

View file

@ -58,6 +58,7 @@ func FuzzDig(f *testing.F) {
"stats", "nostats",
"all", "noall",
"idnout", "noidnout",
"class", "noclass",
"invalid",
}
@ -66,6 +67,10 @@ func FuzzDig(f *testing.F) {
}
f.Fuzz(func(t *testing.T, orig string) {
// Get rid of outputs
// os.Stdout = os.NewFile(0, os.DevNull)
// os.Stderr = os.NewFile(0, os.DevNull)
opts := new(util.Options)
opts.Logger = util.InitLogger(0)
if err := cli.ParseDig(orig, opts); err != nil {

View file

@ -13,7 +13,7 @@ import (
"golang.org/x/net/idna"
)
// ParseMiscArgs parses the wildcard arguments, drill style.
// ParseMiscArgs parses the wildcard arguments, dig style.
// Only one command is supported at a time, so any extra information overrides previous.
func ParseMiscArgs(args []string, opts *util.Options) error {
for _, arg := range args {

View file

@ -166,6 +166,8 @@ func FuzzParseArgs(f *testing.F) {
}
f.Fuzz(func(t *testing.T, arg string) {
// Get rid of outputs
args := []string{arg}
opts := new(util.Options)
opts.Logger = util.InitLogger(0)

@ -1 +1 @@
Subproject commit 4974d316fc3be3c28b54af5188860f8cfb2bdd6b
Subproject commit 96f2699a2f22a5bdcf37a48d0a20fd85c96bcc81

2
go.mod
View file

@ -31,7 +31,7 @@ require (
github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d // indirect
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
golang.org/x/text v0.3.7 // indirect

22
go.sum
View file

@ -79,6 +79,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d h1:3qF+Z8Hkrw9sOhrFHti9TlB1Hkac1x+DNRkv0XQiFjo=
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 h1:tnebWN09GYg9OLPss1KXj8txwZc6X6uMr6VFdcGNbHw=
golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@ -115,23 +117,6 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d h1:Sv5ogFZatcgIMMtBSTTAgMYsicp25MXBubjXNDKwm80=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 h1:9vYwv7OjYaky/tlAeD7C4oC9EsPTlaFl1H2jS++V+ME=
golang.org/x/sys v0.0.0-20220804214406-8e32c043e418/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664 h1:v1W7bwXHsnLLloWYTVEdvGvA7BHMeBYsPcF0GLDxIRs=
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2 h1:fqTvyMIIj+HRzMmnzr9NtpHP6uVpvB5fkHcgPDC4nu8=
golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 h1:Sx/u41w+OwrInGdEckYmEuU5gHoGSL4QbDz3S9s6j4U=
golang.org/x/sys v0.0.0-20220818161305-2296e01440c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24 h1:TyKJRhyo17yWxOMCTHKWrc5rddHORMlnZ/j57umaUd8=
golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 h1:UiNENfZ8gDvpiWw7IpOMQ27spWmThO1RwwdQVbJahJM=
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@ -157,8 +142,10 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
@ -167,6 +154,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=

View file

@ -57,7 +57,10 @@ func run() (opts util.Options, code int, err error) {
return opts, 10, fmt.Errorf("format print: %w", err)
}
} else {
str = query.ToString(resp, opts)
str, err = query.ToString(resp, opts)
if err != nil {
return opts, 15, fmt.Errorf("standard print: %w", err)
}
}
fmt.Println(str)

View file

@ -11,6 +11,9 @@ import (
)
func TestMain(t *testing.T) { //nolint: paralleltest // Race conditions
os.Stdout = os.NewFile(0, os.DevNull)
os.Stderr = os.NewFile(0, os.DevNull)
old := os.Args
os.Args = []string{"awl", "+yaml", "@1.1.1.1"}
@ -30,6 +33,8 @@ func TestMain(t *testing.T) { //nolint: paralleltest // Race conditions
func TestHelp(t *testing.T) {
old := os.Args
os.Stdout = os.NewFile(0, os.DevNull)
os.Stderr = os.NewFile(0, os.DevNull)
os.Args = []string{"awl", "-h"}

View file

@ -114,9 +114,7 @@ func TestRealPrint(t *testing.T) {
ShowQuery: true,
RD: true,
Verbosity: 0,
ShowTTL: true,
Identify: true,
YAML: false,
ShowTTL: false,
Display: util.Displays{
Comments: true,
Question: true,
@ -177,11 +175,13 @@ func TestRealPrint(t *testing.T) {
assert.NilError(t, err)
if test.JSON || test.XML || test.YAML {
str, err := query.PrintSpecial(resp.DNS, test)
str := ""
str, err = query.PrintSpecial(resp.DNS, test)
assert.NilError(t, err)
assert.Assert(t, str != "")
}
str := query.ToString(resp, test)
str, err := query.ToString(resp, test)
assert.NilError(t, err)
assert.Assert(t, str != "")
})
}
@ -197,5 +197,8 @@ func TestBadFormat(t *testing.T) {
func TestEmpty(t *testing.T) {
t.Parallel()
assert.Assert(t, query.ToString(util.Response{}, util.Options{}) == "<nil> MsgHdr")
str, err := query.ToString(util.Response{}, util.Options{})
assert.Error(t, err, "no message")
assert.Assert(t, str == "<nil> MsgHdr")
}

View file

@ -118,10 +118,14 @@ func CreateQuery(opts util.Options) (util.Response, error) {
} else {
temp := opts.Display.Statistics
opts.Display.Statistics = false
str = ToString(util.Response{
str, err = ToString(util.Response{
DNS: req,
RTT: 0,
}, opts)
if err != nil {
return util.Response{}, err
}
opts.Display.Statistics = temp
str += "\n;; QUERY SIZE: " + strconv.Itoa(req.Len()) + "\n"
}

View file

@ -110,10 +110,12 @@ func TestCreateQ(t *testing.T) {
assert.Assert(t, res != util.Response{})
str, err := query.PrintSpecial(res.DNS, opt)
assert.NilError(t, err)
assert.Assert(t, str != "")
str = query.ToString(res, opt)
str, err = query.ToString(res, opt)
assert.NilError(t, err)
assert.Assert(t, str != "")
})
}

View file

@ -3,12 +3,15 @@
package query
import (
"errors"
"fmt"
"strconv"
"strings"
"time"
"git.froth.zone/sam/awl/util"
"github.com/miekg/dns"
"golang.org/x/net/idna"
)
// Message is for overall DNS responses.
@ -45,9 +48,9 @@ type Answer struct {
// ToString turns the response into something that looks a lot like dig
//
// Much of this is taken from https://github.com/miekg/dns/blob/master/msg.go#L900
func ToString(res util.Response, opts util.Options) string {
func ToString(res util.Response, opts util.Options) (string, error) {
if res.DNS == nil {
return "<nil> MsgHdr"
return "<nil> MsgHdr", errNoMessage
}
var (
@ -77,7 +80,12 @@ func ToString(res util.Response, opts util.Options) string {
}
for _, r := range res.DNS.Question {
s += r.String() + "\n"
str, err := stringParse(r.String(), false, opts)
if err != nil {
return "", fmt.Errorf("%w", err)
}
s += str + "\n"
}
}
}
@ -90,7 +98,12 @@ func ToString(res util.Response, opts util.Options) string {
for _, r := range res.DNS.Answer {
if r != nil {
s += r.String() + "\n"
str, err := stringParse(r.String(), true, opts)
if err != nil {
return "", fmt.Errorf("%w", err)
}
s += str + "\n"
}
}
}
@ -104,7 +117,12 @@ func ToString(res util.Response, opts util.Options) string {
for _, r := range res.DNS.Ns {
if r != nil {
s += r.String() + "\n"
str, err := stringParse(r.String(), true, opts)
if err != nil {
return "", fmt.Errorf("%w", err)
}
s += str + "\n"
}
}
}
@ -118,7 +136,12 @@ func ToString(res util.Response, opts util.Options) string {
for _, r := range res.DNS.Extra {
if r != nil && r.Header().Rrtype != dns.TypeOPT {
s += r.String() + "\n"
str, err := stringParse(r.String(), true, opts)
if err != nil {
return "", fmt.Errorf("%w", err)
}
s += str + "\n"
}
}
}
@ -163,5 +186,58 @@ func ToString(res util.Response, opts util.Options) string {
}
}
return s
return s, nil
}
func stringParse(str string, isAns bool, opts util.Options) (string, error) {
split := strings.Split(str, "\t")
// Make edits if so requested
// TODO: make less ew?
// This exists because the question section should be left alone EXCEPT for punycode.
if isAns {
if !opts.ShowTTL {
// Remove from existence
split = append(split[:1], split[2:]...)
}
if !opts.ShowClass {
// Position depends on if the TTL is there or not.
if opts.ShowTTL {
split = append(split[:2], split[3:]...)
} else {
split = append(split[:1], split[2:]...)
}
}
if opts.HumanTTL {
ttl, _ := strconv.Atoi(split[1])
split[1] = (time.Duration(ttl) * time.Second).String()
}
}
if opts.Display.UcodeTranslate {
var (
err error
semi string
)
if strings.HasPrefix(split[0], ";") {
split[0] = strings.TrimPrefix(split[0], ";")
semi = ";"
}
split[0], err = idna.ToUnicode(split[0])
if err != nil {
return "", fmt.Errorf("punycode: %w", err)
}
split[0] = semi + split[0]
}
return strings.Join(split, "\t"), nil
}
var errNoMessage = errors.New("no message")

View file

@ -21,6 +21,7 @@ type Options struct {
Display Displays
TC bool
ShowTTL bool
ShowClass bool
ShowQuery bool
AA bool
AD bool