Pull request 2097: 6420-ipset-currenly-known-sets

Updates #6420.

Squashed commit of the following:

commit 9c08b4206845547bae07b5c456eaf74df4d55921
Merge: a9ee2fe56 083abaac0
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Dec 6 19:20:53 2023 +0300

    Merge branch 'master' into 6420-ipset-currenly-known-sets

commit a9ee2fe5603168ce75a5c8cba5b2356c039b0970
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Dec 6 18:26:01 2023 +0300

    all: imp docs

commit fabaab0cc40256cb486366e1cc2d345159178cd1
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Dec 6 15:00:58 2023 +0300

    ipset: currently known sets
This commit is contained in:
Stanislav Chzhen 2023-12-06 19:28:56 +03:00
parent 083abaac09
commit 214175eb41
4 changed files with 36 additions and 22 deletions

View file

@ -269,8 +269,9 @@ func (m *manager) parseIpsetConfig(ipsetConf []string) (err error) {
return err return err
} }
currentlyKnown := map[string]props{}
for _, p := range all { for _, p := range all {
m.nameToIpset[p.name] = p currentlyKnown[p.name] = p
} }
for i, confStr := range ipsetConf { for i, confStr := range ipsetConf {
@ -281,7 +282,7 @@ func (m *manager) parseIpsetConfig(ipsetConf []string) (err error) {
} }
var ipsets []props var ipsets []props
ipsets, err = m.ipsets(ipsetNames) ipsets, err = m.ipsets(ipsetNames, currentlyKnown)
if err != nil { if err != nil {
return fmt.Errorf("getting ipsets from config line at idx %d: %w", i, err) return fmt.Errorf("getting ipsets from config line at idx %d: %w", i, err)
} }
@ -297,35 +298,43 @@ func (m *manager) parseIpsetConfig(ipsetConf []string) (err error) {
// ipsetProps returns the properties of an ipset with the given name. // ipsetProps returns the properties of an ipset with the given name.
// //
// Additional header data query. See https://github.com/AdguardTeam/AdGuardHome/issues/6420. // Additional header data query. See https://github.com/AdguardTeam/AdGuardHome/issues/6420.
func (m *manager) ipsetProps(p props) (err error) { //
// TODO(s.chzhen): Use *props.
func (m *manager) ipsetProps(name string) (p props, err error) {
// The family doesn't seem to matter when we use a header query, so // The family doesn't seem to matter when we use a header query, so
// query only the IPv4 one. // query only the IPv4 one.
// //
// TODO(a.garipov): Find out if this is a bug or a feature. // TODO(a.garipov): Find out if this is a bug or a feature.
var res *ipset.HeaderPolicy var res *ipset.HeaderPolicy
res, err = m.ipv4Conn.Header(p.name) res, err = m.ipv4Conn.Header(name)
if err != nil { if err != nil {
return err return props{}, err
} }
if res == nil || res.Family == nil { if res == nil || res.Family == nil {
return errors.Error("empty response or no family data") return props{}, errors.Error("empty response or no family data")
} }
family := netfilter.ProtoFamily(res.Family.Value) family := netfilter.ProtoFamily(res.Family.Value)
if family != netfilter.ProtoIPv4 && family != netfilter.ProtoIPv6 { if family != netfilter.ProtoIPv4 && family != netfilter.ProtoIPv6 {
return fmt.Errorf("unexpected ipset family %q", family) return props{}, fmt.Errorf("unexpected ipset family %q", family)
} }
p.family = family typeName := res.TypeName.Get()
return nil return props{
name: name,
typeName: typeName,
family: family,
isPersistent: false,
}, nil
} }
// ipsets returns currently known ipsets. // ipsets returns ipset properties of currently known ipsets. It also makes an
func (m *manager) ipsets(names []string) (sets []props, err error) { // additional ipset header data query if needed.
func (m *manager) ipsets(names []string, currentlyKnown map[string]props) (sets []props, err error) {
for _, n := range names { for _, n := range names {
p, ok := m.nameToIpset[n] p, ok := currentlyKnown[n]
if !ok { if !ok {
return nil, fmt.Errorf("unknown ipset %q", n) return nil, fmt.Errorf("unknown ipset %q", n)
} }
@ -337,12 +346,13 @@ func (m *manager) ipsets(names []string) (sets []props, err error) {
p.family, p.family,
) )
err = m.ipsetProps(p) p, err = m.ipsetProps(n)
if err != nil { if err != nil {
return nil, fmt.Errorf("%q %q making header query: %w", p.name, p.typeName, err) return nil, fmt.Errorf("%q %q making header query: %w", p.name, p.typeName, err)
} }
} }
m.nameToIpset[n] = p
sets = append(sets, p) sets = append(sets, p)
} }

View file

@ -339,9 +339,6 @@ func (r dayRange) toDayConfigJSON() (j *dayConfigJSON) {
// weeklyConfigJSON is the JSON configuration structure of Weekly. // weeklyConfigJSON is the JSON configuration structure of Weekly.
type weeklyConfigJSON struct { type weeklyConfigJSON struct {
// TimeZone is the local time zone.
TimeZone string `json:"time_zone"`
// Days of the week. // Days of the week.
Sunday *dayConfigJSON `json:"sun,omitempty"` Sunday *dayConfigJSON `json:"sun,omitempty"`
@ -351,6 +348,9 @@ type weeklyConfigJSON struct {
Thursday *dayConfigJSON `json:"thu,omitempty"` Thursday *dayConfigJSON `json:"thu,omitempty"`
Friday *dayConfigJSON `json:"fri,omitempty"` Friday *dayConfigJSON `json:"fri,omitempty"`
Saturday *dayConfigJSON `json:"sat,omitempty"` Saturday *dayConfigJSON `json:"sat,omitempty"`
// TimeZone is the local time zone.
TimeZone string `json:"time_zone"`
} }
// dayConfigJSON is the JSON configuration structure of dayRange. // dayConfigJSON is the JSON configuration structure of dayRange.

View file

@ -163,10 +163,10 @@ yaml: "bad"
} }
testCases := []struct { testCases := []struct {
want *Weekly
name string name string
wantErrMsg string wantErrMsg string
data []byte data []byte
want *Weekly
}{{ }{{
name: "empty", name: "empty",
wantErrMsg: "", wantErrMsg: "",
@ -228,9 +228,9 @@ func TestWeekly_MarshalYAML(t *testing.T) {
} }
testCases := []struct { testCases := []struct {
want *Weekly
name string name string
data []byte data []byte
want *Weekly
}{{ }{{
name: "empty", name: "empty",
data: []byte(""), data: []byte(""),
@ -263,8 +263,8 @@ func TestWeekly_MarshalYAML(t *testing.T) {
func TestWeekly_Validate(t *testing.T) { func TestWeekly_Validate(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
in dayRange
wantErrMsg string wantErrMsg string
in dayRange
}{{ }{{
name: "empty", name: "empty",
wantErrMsg: "", wantErrMsg: "",
@ -298,8 +298,8 @@ func TestWeekly_Validate(t *testing.T) {
func TestDayRange_Validate(t *testing.T) { func TestDayRange_Validate(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
in dayRange
wantErrMsg string wantErrMsg string
in dayRange
}{{ }{{
name: "empty", name: "empty",
wantErrMsg: "", wantErrMsg: "",
@ -413,10 +413,10 @@ func TestWeekly_UnmarshalJSON(t *testing.T) {
} }
testCases := []struct { testCases := []struct {
want *Weekly
name string name string
wantErrMsg string wantErrMsg string
data []byte data []byte
want *Weekly
}{{ }{{
name: "empty", name: "empty",
wantErrMsg: "unexpected end of JSON input", wantErrMsg: "unexpected end of JSON input",
@ -478,9 +478,9 @@ func TestWeekly_MarshalJSON(t *testing.T) {
} }
testCases := []struct { testCases := []struct {
want *Weekly
name string name string
data []byte data []byte
want *Weekly
}{{ }{{
name: "empty", name: "empty",
data: []byte(""), data: []byte(""),

View file

@ -218,6 +218,7 @@ run_linter gocognit --over='10'\
./internal/filtering/hashprefix/\ ./internal/filtering/hashprefix/\
./internal/filtering/rulelist/\ ./internal/filtering/rulelist/\
./internal/filtering/safesearch/\ ./internal/filtering/safesearch/\
./internal/ipset\
./internal/next/\ ./internal/next/\
./internal/rdns/\ ./internal/rdns/\
./internal/schedule/\ ./internal/schedule/\
@ -257,9 +258,11 @@ run_linter fieldalignment \
./internal/filtering/rewrite/\ ./internal/filtering/rewrite/\
./internal/filtering/rulelist/\ ./internal/filtering/rulelist/\
./internal/filtering/safesearch/\ ./internal/filtering/safesearch/\
./internal/ipset/\
./internal/next/...\ ./internal/next/...\
./internal/querylog/\ ./internal/querylog/\
./internal/rdns/\ ./internal/rdns/\
./internal/schedule/\
./internal/stats/\ ./internal/stats/\
./internal/updater/\ ./internal/updater/\
./internal/version/\ ./internal/version/\
@ -287,6 +290,7 @@ run_linter gosec --quiet\
./internal/filtering/rewrite/\ ./internal/filtering/rewrite/\
./internal/filtering/rulelist/\ ./internal/filtering/rulelist/\
./internal/filtering/safesearch/\ ./internal/filtering/safesearch/\
./internal/ipset/\
./internal/next/\ ./internal/next/\
./internal/rdns/\ ./internal/rdns/\
./internal/schedule/\ ./internal/schedule/\