Skip to content

Commit

Permalink
Merge branch 'master' into 1273-querylog-client-name
Browse files Browse the repository at this point in the history
  • Loading branch information
ainar-g committed Apr 1, 2021
2 parents cda92c3 + 2e4e2f6 commit 4b2a2db
Show file tree
Hide file tree
Showing 45 changed files with 1,858 additions and 475 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/Bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Please answer the following questions for yourself before submitting an issue. *

### Issue Details

<!-- Please include all relevant details about the environment you experienced the bug in. -->
<!-- Please include all relevant details about the environment you experienced the bug in. If possible, include the result of running `./AdGuardHome -v --version` from the installation directory. -->

* **Version of AdGuard Home server:**
* <!-- (e.g. v0.123.4) -->
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ and this project adheres to
### Added

- Search by clients' names in the query log ([#1273]).
- Verbose version output with `-v --version` ([#2416]).
- The ability to set a custom TLD for known local-network hosts ([#2393]).
- The ability to serve DNS queries on multiple hosts and interfaces ([#1401]).
- `ips` and `text` DHCP server options ([#2385]).
- `SRV` records support in `$dnsrewrite` filters ([#2533]).

### Changed

- The reverse lookup for local addresses is now performed via local resolvers
([#2704]).
- Stricter validation of the IP addresses of static leases in the DHCP server
with regards to the netmask ([#2838]).
- Stricter validation of `$dnsrewrite` filter modifier parameters ([#2498]).
Expand All @@ -34,6 +37,7 @@ and this project adheres to

### Fixed

- Assumption that MAC addresses always have the length of 6 octets ([#2828]).
- Support for more than one `/24` subnet in DHCP ([#2541]).
- Invalid filenames in the `mobileconfig` API responses ([#2835]).

Expand All @@ -46,9 +50,12 @@ and this project adheres to
[#2385]: https://github.com/AdguardTeam/AdGuardHome/issues/2385
[#2393]: https://github.com/AdguardTeam/AdGuardHome/issues/2393
[#2412]: https://github.com/AdguardTeam/AdGuardHome/issues/2412
[#2416]: https://github.com/AdguardTeam/AdGuardHome/issues/2416
[#2498]: https://github.com/AdguardTeam/AdGuardHome/issues/2498
[#2533]: https://github.com/AdguardTeam/AdGuardHome/issues/2533
[#2541]: https://github.com/AdguardTeam/AdGuardHome/issues/2541
[#2704]: https://github.com/AdguardTeam/AdGuardHome/issues/2704
[#2828]: https://github.com/AdguardTeam/AdGuardHome/issues/2828
[#2835]: https://github.com/AdguardTeam/AdGuardHome/issues/2835
[#2838]: https://github.com/AdguardTeam/AdGuardHome/issues/2838

Expand Down
4 changes: 2 additions & 2 deletions HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,8 @@ on GitHub and most other Markdown renderers. -->

### <a id="formatting" href="#formatting">Formatting</a>

* Add an empty line before `break`, `continue`, `fallthrough`, and `return`,
unless it's the only statement in that block.
* Decorate `break`, `continue`, `fallthrough`, `return`, and other function
exit points with empty lines unless it's the only statement in that block.

* Use `gofumpt --extra -s`.

Expand Down
62 changes: 31 additions & 31 deletions client/src/__locales/en.json

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions internal/aghnet/addr.go
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)
}
}
57 changes: 57 additions & 0 deletions internal/aghnet/addr_test.go
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())
}
})
}
}
79 changes: 79 additions & 0 deletions internal/aghnet/exchanger.go
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...)
}
64 changes: 64 additions & 0 deletions internal/aghnet/exchanger_test.go
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)
})
}
73 changes: 0 additions & 73 deletions internal/aghnet/ipdetector.go

This file was deleted.

Loading

0 comments on commit 4b2a2db

Please sign in to comment.