2024-01-30 15:43:51 +00:00
|
|
|
package filtering
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/netip"
|
|
|
|
"testing"
|
|
|
|
"testing/fstest"
|
|
|
|
|
|
|
|
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
|
|
|
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
|
2024-04-02 18:22:19 +01:00
|
|
|
"github.com/AdguardTeam/AdGuardHome/internal/filtering/rulelist"
|
2024-01-30 15:43:51 +00:00
|
|
|
"github.com/AdguardTeam/golibs/testutil"
|
|
|
|
"github.com/AdguardTeam/urlfilter/rules"
|
|
|
|
"github.com/miekg/dns"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestDNSFilter_CheckHost_hostsContainer(t *testing.T) {
|
|
|
|
addrv4 := netip.MustParseAddr("1.2.3.4")
|
|
|
|
addrv6 := netip.MustParseAddr("::1")
|
|
|
|
addrMapped := netip.MustParseAddr("::ffff:1.2.3.4")
|
|
|
|
addrv4Dup := netip.MustParseAddr("4.3.2.1")
|
|
|
|
|
|
|
|
data := fmt.Sprintf(
|
|
|
|
""+
|
|
|
|
"%[1]s v4.host.example\n"+
|
|
|
|
"%[2]s v6.host.example\n"+
|
|
|
|
"%[3]s mapped.host.example\n"+
|
|
|
|
"%[4]s v4.host.with-dup\n"+
|
|
|
|
"%[4]s v4.host.with-dup\n",
|
|
|
|
addrv4,
|
|
|
|
addrv6,
|
|
|
|
addrMapped,
|
|
|
|
addrv4Dup,
|
|
|
|
)
|
|
|
|
|
|
|
|
files := fstest.MapFS{
|
|
|
|
"hosts": &fstest.MapFile{
|
|
|
|
Data: []byte(data),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
watcher := &aghtest.FSWatcher{
|
2024-03-12 14:45:11 +00:00
|
|
|
OnStart: func() (_ error) { panic("not implemented") },
|
2024-01-30 15:43:51 +00:00
|
|
|
OnEvents: func() (e <-chan struct{}) { return nil },
|
|
|
|
OnAdd: func(name string) (err error) { return nil },
|
|
|
|
OnClose: func() (err error) { return nil },
|
|
|
|
}
|
|
|
|
hc, err := aghnet.NewHostsContainer(files, watcher, "hosts")
|
|
|
|
require.NoError(t, err)
|
|
|
|
testutil.CleanupAndRequireSuccess(t, hc.Close)
|
|
|
|
|
|
|
|
conf := &Config{
|
|
|
|
EtcHosts: hc,
|
|
|
|
}
|
|
|
|
f, err := New(conf, nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
setts := &Settings{
|
|
|
|
FilteringEnabled: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
host string
|
|
|
|
wantRules []*ResultRule
|
|
|
|
wantResps []rules.RRValue
|
|
|
|
dtyp uint16
|
|
|
|
}{{
|
|
|
|
name: "v4",
|
|
|
|
host: "v4.host.example",
|
|
|
|
dtyp: dns.TypeA,
|
|
|
|
wantRules: []*ResultRule{{
|
|
|
|
Text: "1.2.3.4 v4.host.example",
|
2024-04-02 18:22:19 +01:00
|
|
|
FilterListID: rulelist.URLFilterIDEtcHosts,
|
2024-01-30 15:43:51 +00:00
|
|
|
}},
|
|
|
|
wantResps: []rules.RRValue{addrv4},
|
|
|
|
}, {
|
|
|
|
name: "v6",
|
|
|
|
host: "v6.host.example",
|
|
|
|
dtyp: dns.TypeAAAA,
|
|
|
|
wantRules: []*ResultRule{{
|
|
|
|
Text: "::1 v6.host.example",
|
2024-04-02 18:22:19 +01:00
|
|
|
FilterListID: rulelist.URLFilterIDEtcHosts,
|
2024-01-30 15:43:51 +00:00
|
|
|
}},
|
|
|
|
wantResps: []rules.RRValue{addrv6},
|
|
|
|
}, {
|
|
|
|
name: "mapped",
|
|
|
|
host: "mapped.host.example",
|
|
|
|
dtyp: dns.TypeAAAA,
|
|
|
|
wantRules: []*ResultRule{{
|
|
|
|
Text: "::ffff:1.2.3.4 mapped.host.example",
|
2024-04-02 18:22:19 +01:00
|
|
|
FilterListID: rulelist.URLFilterIDEtcHosts,
|
2024-01-30 15:43:51 +00:00
|
|
|
}},
|
|
|
|
wantResps: []rules.RRValue{addrMapped},
|
|
|
|
}, {
|
|
|
|
name: "ptr",
|
|
|
|
host: "4.3.2.1.in-addr.arpa",
|
|
|
|
dtyp: dns.TypePTR,
|
|
|
|
wantRules: []*ResultRule{{
|
|
|
|
Text: "1.2.3.4 v4.host.example",
|
2024-04-02 18:22:19 +01:00
|
|
|
FilterListID: rulelist.URLFilterIDEtcHosts,
|
2024-01-30 15:43:51 +00:00
|
|
|
}},
|
|
|
|
wantResps: []rules.RRValue{"v4.host.example"},
|
|
|
|
}, {
|
|
|
|
name: "ptr-mapped",
|
|
|
|
host: "4.0.3.0.2.0.1.0.f.f.f.f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa",
|
|
|
|
dtyp: dns.TypePTR,
|
|
|
|
wantRules: []*ResultRule{{
|
|
|
|
Text: "::ffff:1.2.3.4 mapped.host.example",
|
2024-04-02 18:22:19 +01:00
|
|
|
FilterListID: rulelist.URLFilterIDEtcHosts,
|
2024-01-30 15:43:51 +00:00
|
|
|
}},
|
|
|
|
wantResps: []rules.RRValue{"mapped.host.example"},
|
|
|
|
}, {
|
|
|
|
name: "not_found_v4",
|
|
|
|
host: "non.existent.example",
|
|
|
|
dtyp: dns.TypeA,
|
|
|
|
wantRules: nil,
|
|
|
|
wantResps: nil,
|
|
|
|
}, {
|
|
|
|
name: "not_found_v6",
|
|
|
|
host: "non.existent.example",
|
|
|
|
dtyp: dns.TypeAAAA,
|
|
|
|
wantRules: nil,
|
|
|
|
wantResps: nil,
|
|
|
|
}, {
|
|
|
|
name: "not_found_ptr",
|
|
|
|
host: "4.3.2.2.in-addr.arpa",
|
|
|
|
dtyp: dns.TypePTR,
|
|
|
|
wantRules: nil,
|
|
|
|
wantResps: nil,
|
|
|
|
}, {
|
|
|
|
name: "v4_mismatch",
|
|
|
|
host: "v4.host.example",
|
|
|
|
dtyp: dns.TypeAAAA,
|
|
|
|
wantRules: []*ResultRule{{
|
|
|
|
Text: fmt.Sprintf("%s v4.host.example", addrv4),
|
2024-04-02 18:22:19 +01:00
|
|
|
FilterListID: rulelist.URLFilterIDEtcHosts,
|
2024-01-30 15:43:51 +00:00
|
|
|
}},
|
|
|
|
wantResps: nil,
|
|
|
|
}, {
|
|
|
|
name: "v6_mismatch",
|
|
|
|
host: "v6.host.example",
|
|
|
|
dtyp: dns.TypeA,
|
|
|
|
wantRules: []*ResultRule{{
|
|
|
|
Text: fmt.Sprintf("%s v6.host.example", addrv6),
|
2024-04-02 18:22:19 +01:00
|
|
|
FilterListID: rulelist.URLFilterIDEtcHosts,
|
2024-01-30 15:43:51 +00:00
|
|
|
}},
|
|
|
|
wantResps: nil,
|
|
|
|
}, {
|
|
|
|
name: "wrong_ptr",
|
|
|
|
host: "4.3.2.1.ip6.arpa",
|
|
|
|
dtyp: dns.TypePTR,
|
|
|
|
wantRules: nil,
|
|
|
|
wantResps: nil,
|
|
|
|
}, {
|
|
|
|
name: "unsupported_type",
|
|
|
|
host: "v4.host.example",
|
|
|
|
dtyp: dns.TypeCNAME,
|
|
|
|
wantRules: nil,
|
|
|
|
wantResps: nil,
|
|
|
|
}, {
|
|
|
|
name: "v4_dup",
|
|
|
|
host: "v4.host.with-dup",
|
|
|
|
dtyp: dns.TypeA,
|
|
|
|
wantRules: []*ResultRule{{
|
|
|
|
Text: "4.3.2.1 v4.host.with-dup",
|
2024-04-02 18:22:19 +01:00
|
|
|
FilterListID: rulelist.URLFilterIDEtcHosts,
|
2024-01-30 15:43:51 +00:00
|
|
|
}},
|
|
|
|
wantResps: []rules.RRValue{addrv4Dup},
|
|
|
|
}}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
var res Result
|
|
|
|
res, err = f.CheckHost(tc.host, tc.dtyp, setts)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
if len(tc.wantRules) == 0 {
|
|
|
|
assert.Empty(t, res.Rules)
|
|
|
|
assert.Nil(t, res.DNSRewriteResult)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
require.NotNil(t, res.DNSRewriteResult)
|
|
|
|
require.Contains(t, res.DNSRewriteResult.Response, tc.dtyp)
|
|
|
|
|
|
|
|
assert.Equal(t, tc.wantResps, res.DNSRewriteResult.Response[tc.dtyp])
|
|
|
|
assert.Equal(t, tc.wantRules, res.Rules)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|