-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into 1273-querylog-client-name
- Loading branch information
Showing
45 changed files
with
1,858 additions
and
475 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package aghnet | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
|
||
"github.com/AdguardTeam/AdGuardHome/internal/agherr" | ||
) | ||
|
||
// ValidateHardwareAddress returns an error if hwa is not a valid EUI-48, | ||
// EUI-64, or 20-octet InfiniBand link-layer address. | ||
func ValidateHardwareAddress(hwa net.HardwareAddr) (err error) { | ||
defer agherr.Annotate("validating hardware address %q: %w", &err, hwa) | ||
|
||
switch l := len(hwa); l { | ||
case 0: | ||
return agherr.Error("address is empty") | ||
case 6, 8, 20: | ||
return nil | ||
default: | ||
return fmt.Errorf("bad len: %d", l) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package aghnet | ||
|
||
import ( | ||
"net" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestValidateHardwareAddress(t *testing.T) { | ||
testCases := []struct { | ||
name string | ||
wantErrMsg string | ||
in net.HardwareAddr | ||
}{{ | ||
name: "success_eui_48", | ||
wantErrMsg: "", | ||
in: net.HardwareAddr{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}, | ||
}, { | ||
name: "success_eui_64", | ||
wantErrMsg: "", | ||
in: net.HardwareAddr{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, | ||
}, { | ||
name: "success_infiniband", | ||
wantErrMsg: "", | ||
in: net.HardwareAddr{ | ||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | ||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, | ||
0x10, 0x11, 0x12, 0x13, | ||
}, | ||
}, { | ||
name: "error_nil", | ||
wantErrMsg: `validating hardware address "": address is empty`, | ||
in: nil, | ||
}, { | ||
name: "error_empty", | ||
wantErrMsg: `validating hardware address "": address is empty`, | ||
in: net.HardwareAddr{}, | ||
}, { | ||
name: "error_bad", | ||
wantErrMsg: `validating hardware address "00:01:02:03": bad len: 4`, | ||
in: net.HardwareAddr{0x00, 0x01, 0x02, 0x03}, | ||
}} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
err := ValidateHardwareAddress(tc.in) | ||
if tc.wantErrMsg == "" { | ||
assert.NoError(t, err) | ||
} else { | ||
require.Error(t, err) | ||
assert.Equal(t, tc.wantErrMsg, err.Error()) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package aghnet | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/AdguardTeam/AdGuardHome/internal/agherr" | ||
"github.com/AdguardTeam/dnsproxy/upstream" | ||
"github.com/miekg/dns" | ||
) | ||
|
||
// This package is not the best place for this functionality, but we put it here | ||
// since we need to use it in both rDNS (home) and dnsServer (dnsforward). | ||
|
||
// NoUpstreamsErr should be returned when there are no upstreams inside | ||
// Exchanger implementation. | ||
const NoUpstreamsErr agherr.Error = "no upstreams specified" | ||
|
||
// Exchanger represents an object able to resolve DNS messages. | ||
// | ||
// TODO(e.burkov): Maybe expand with method like ExchangeParallel to be able to | ||
// use user's upstream mode settings. Also, think about Update method to | ||
// refresh the internal state. | ||
type Exchanger interface { | ||
Exchange(req *dns.Msg) (resp *dns.Msg, err error) | ||
} | ||
|
||
// multiAddrExchanger is the default implementation of Exchanger interface. | ||
type multiAddrExchanger struct { | ||
ups []upstream.Upstream | ||
} | ||
|
||
// NewMultiAddrExchanger creates an Exchanger instance from passed addresses. | ||
// It returns an error if any of addrs failed to become an upstream. | ||
func NewMultiAddrExchanger(addrs []string, timeout time.Duration) (e Exchanger, err error) { | ||
defer agherr.Annotate("exchanger: %w", &err) | ||
|
||
if len(addrs) == 0 { | ||
return &multiAddrExchanger{}, nil | ||
} | ||
|
||
var ups []upstream.Upstream = make([]upstream.Upstream, 0, len(addrs)) | ||
for _, addr := range addrs { | ||
var u upstream.Upstream | ||
u, err = upstream.AddressToUpstream(addr, upstream.Options{Timeout: timeout}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
ups = append(ups, u) | ||
} | ||
|
||
return &multiAddrExchanger{ups: ups}, nil | ||
} | ||
|
||
// Exсhange performs a query to each resolver until first response. | ||
func (e *multiAddrExchanger) Exchange(req *dns.Msg) (resp *dns.Msg, err error) { | ||
defer agherr.Annotate("exchanger: %w", &err) | ||
|
||
// TODO(e.burkov): Maybe prohibit the initialization without upstreams. | ||
if len(e.ups) == 0 { | ||
return nil, NoUpstreamsErr | ||
} | ||
|
||
var errs []error | ||
for _, u := range e.ups { | ||
resp, err = u.Exchange(req) | ||
if err != nil { | ||
errs = append(errs, err) | ||
|
||
continue | ||
} | ||
|
||
if resp != nil { | ||
return resp, nil | ||
} | ||
} | ||
|
||
return nil, agherr.Many("can't exchange", errs...) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package aghnet | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/AdguardTeam/AdGuardHome/internal/aghtest" | ||
"github.com/AdguardTeam/dnsproxy/upstream" | ||
"github.com/miekg/dns" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestNewMultiAddrExchanger(t *testing.T) { | ||
var e Exchanger | ||
var err error | ||
|
||
t.Run("empty", func(t *testing.T) { | ||
e, err = NewMultiAddrExchanger([]string{}, 0) | ||
require.NoError(t, err) | ||
assert.NotNil(t, e) | ||
}) | ||
|
||
t.Run("successful", func(t *testing.T) { | ||
e, err = NewMultiAddrExchanger([]string{"www.example.com"}, 0) | ||
require.NoError(t, err) | ||
assert.NotNil(t, e) | ||
}) | ||
|
||
t.Run("unsuccessful", func(t *testing.T) { | ||
e, err = NewMultiAddrExchanger([]string{"invalid-proto://www.example.com"}, 0) | ||
require.Error(t, err) | ||
assert.Nil(t, e) | ||
}) | ||
} | ||
|
||
func TestMultiAddrExchanger_Exchange(t *testing.T) { | ||
e := &multiAddrExchanger{} | ||
|
||
t.Run("error", func(t *testing.T) { | ||
e.ups = []upstream.Upstream{&aghtest.TestErrUpstream{}} | ||
|
||
resp, err := e.Exchange(nil) | ||
require.Error(t, err) | ||
assert.Nil(t, resp) | ||
}) | ||
|
||
t.Run("success", func(t *testing.T) { | ||
e.ups = []upstream.Upstream{&aghtest.TestUpstream{ | ||
Reverse: map[string][]string{ | ||
"abc": {"cba"}, | ||
}, | ||
}} | ||
|
||
resp, err := e.Exchange(&dns.Msg{ | ||
Question: []dns.Question{{ | ||
Name: "abc", | ||
Qtype: dns.TypePTR, | ||
}}, | ||
}) | ||
require.NoError(t, err) | ||
require.Len(t, resp.Answer, 1) | ||
assert.Equal(t, "cba", resp.Answer[0].Header().Name) | ||
}) | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.