mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2024-11-25 14:35:48 +03:00
4582b1c919
Merge in DNS/adguard-home from 2926-lla-v6 to master
Updates #2926.
Updates #5035.
Squashed commit of the following:
commit 2e770d4b6d4e1ec3f7762f2f2466662983bf146c
Merge: 25c1afc5 893358ea
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Fri Oct 14 15:14:56 2022 +0300
Merge branch 'master' into 2926-lla-v6
commit 25c1afc5f0a5027fafac9dee77618886aefee29c
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Oct 13 18:24:20 2022 +0300
all: imp code, docs
commit 59549c4f74ee17b10eae542d1f1828d4e59894c9
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Tue Oct 11 18:49:09 2022 +0300
dhcpd: use netip initially
commit 1af623096b0517d07752385540f2f750f7f5b3bb
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Fri Sep 30 18:03:52 2022 +0300
all: imp docs, code
commit e9faeb71dbc0e887b25a7f3d5b33a401805f2ae7
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Sep 29 14:56:37 2022 +0300
all: use netip for web
commit 38305e555a6884c3bd1b0839330b942ce0e59093
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Wed Sep 28 19:13:58 2022 +0300
add basic lla
268 lines
6.8 KiB
Go
268 lines
6.8 KiB
Go
//go:build darwin || freebsd || linux || openbsd
|
|
|
|
package dhcpd
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/AdguardTeam/golibs/netutil"
|
|
"github.com/AdguardTeam/golibs/testutil"
|
|
"github.com/insomniacslk/dhcp/dhcpv4"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestParseOpt(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
in string
|
|
wantCode dhcpv4.OptionCode
|
|
wantVal dhcpv4.OptionValue
|
|
wantErrMsg string
|
|
}{{
|
|
name: "hex_success",
|
|
in: "6 hex c0a80101c0a80102",
|
|
wantCode: dhcpv4.GenericOptionCode(6),
|
|
wantVal: dhcpv4.OptionGeneric{Data: []byte{
|
|
0xC0, 0xA8, 0x01, 0x01,
|
|
0xC0, 0xA8, 0x01, 0x02,
|
|
}},
|
|
wantErrMsg: "",
|
|
}, {
|
|
name: "ip_success",
|
|
in: "6 ip 1.2.3.4",
|
|
wantCode: dhcpv4.GenericOptionCode(6),
|
|
wantVal: dhcpv4.IP(net.IP{0x01, 0x02, 0x03, 0x04}),
|
|
wantErrMsg: "",
|
|
}, {
|
|
name: "ips_success",
|
|
in: "6 ips 192.168.1.1,192.168.1.2",
|
|
wantCode: dhcpv4.GenericOptionCode(6),
|
|
wantVal: dhcpv4.IPs([]net.IP{
|
|
{0xC0, 0xA8, 0x01, 0x01},
|
|
{0xC0, 0xA8, 0x01, 0x02},
|
|
}),
|
|
wantErrMsg: "",
|
|
}, {
|
|
name: "text_success",
|
|
in: "252 text http://192.168.1.1/",
|
|
wantCode: dhcpv4.GenericOptionCode(252),
|
|
wantVal: dhcpv4.String("http://192.168.1.1/"),
|
|
wantErrMsg: "",
|
|
}, {
|
|
name: "del_success",
|
|
in: "61 del",
|
|
wantCode: dhcpv4.GenericOptionCode(dhcpv4.OptionClientIdentifier),
|
|
wantVal: dhcpv4.OptionGeneric{Data: nil},
|
|
wantErrMsg: "",
|
|
}, {
|
|
name: "bool_success",
|
|
in: "19 bool true",
|
|
wantCode: dhcpv4.GenericOptionCode(dhcpv4.OptionIPForwarding),
|
|
wantVal: dhcpv4.OptionGeneric{Data: []byte{0x01}},
|
|
wantErrMsg: "",
|
|
}, {
|
|
name: "bool_success_false",
|
|
in: "19 bool F",
|
|
wantCode: dhcpv4.GenericOptionCode(dhcpv4.OptionIPForwarding),
|
|
wantVal: dhcpv4.OptionGeneric{Data: []byte{0x00}},
|
|
wantErrMsg: "",
|
|
}, {
|
|
name: "dur_success",
|
|
in: "24 dur 2h5s",
|
|
wantCode: dhcpv4.GenericOptionCode(dhcpv4.OptionPathMTUAgingTimeout),
|
|
wantVal: dhcpv4.Duration(2*time.Hour + 5*time.Second),
|
|
wantErrMsg: "",
|
|
}, {
|
|
name: "u8_success",
|
|
in: "23 u8 64",
|
|
wantCode: dhcpv4.GenericOptionCode(dhcpv4.OptionDefaultIPTTL),
|
|
wantVal: dhcpv4.OptionGeneric{Data: []byte{0x40}},
|
|
wantErrMsg: "",
|
|
}, {
|
|
name: "u16_success",
|
|
in: "22 u16 1234",
|
|
wantCode: dhcpv4.GenericOptionCode(dhcpv4.OptionMaximumDatagramAssemblySize),
|
|
wantVal: dhcpv4.Uint16(1234),
|
|
wantErrMsg: "",
|
|
}, {
|
|
name: "bad_parts",
|
|
in: "6 ip",
|
|
wantCode: nil,
|
|
wantVal: nil,
|
|
wantErrMsg: `invalid option string "6 ip": bad option format`,
|
|
}, {
|
|
name: "bad_code",
|
|
in: "256 ip 1.1.1.1",
|
|
wantCode: nil,
|
|
wantVal: nil,
|
|
wantErrMsg: `invalid option string "256 ip 1.1.1.1": parsing option code: ` +
|
|
`strconv.ParseUint: parsing "256": value out of range`,
|
|
}, {
|
|
name: "bad_type",
|
|
in: "6 bad 1.1.1.1",
|
|
wantCode: nil,
|
|
wantVal: nil,
|
|
wantErrMsg: `invalid option string "6 bad 1.1.1.1": unknown option type "bad"`,
|
|
}, {
|
|
name: "hex_error",
|
|
in: "6 hex ZZZ",
|
|
wantCode: nil,
|
|
wantVal: nil,
|
|
wantErrMsg: `invalid option string "6 hex ZZZ": decoding hex: ` +
|
|
`encoding/hex: invalid byte: U+005A 'Z'`,
|
|
}, {
|
|
name: "ip_error",
|
|
in: "6 ip 1.2.3.x",
|
|
wantCode: nil,
|
|
wantVal: nil,
|
|
wantErrMsg: "invalid option string \"6 ip 1.2.3.x\": bad ipv4 address \"1.2.3.x\"",
|
|
}, {
|
|
name: "ip_error_v6",
|
|
in: "6 ip ::1234",
|
|
wantCode: nil,
|
|
wantVal: nil,
|
|
wantErrMsg: "invalid option string \"6 ip ::1234\": bad ipv4 address \"::1234\"",
|
|
}, {
|
|
name: "ips_error",
|
|
in: "6 ips 192.168.1.1,192.168.1.x",
|
|
wantCode: nil,
|
|
wantVal: nil,
|
|
wantErrMsg: "invalid option string \"6 ips 192.168.1.1,192.168.1.x\": " +
|
|
"parsing ip at index 1: bad ipv4 address \"192.168.1.x\"",
|
|
}, {
|
|
name: "bool_error",
|
|
in: "19 bool yes",
|
|
wantCode: nil,
|
|
wantVal: nil,
|
|
wantErrMsg: "invalid option string \"19 bool yes\": decoding bool: " +
|
|
"strconv.ParseBool: parsing \"yes\": invalid syntax",
|
|
}, {
|
|
name: "dur_error",
|
|
in: "24 dur 3y",
|
|
wantCode: nil,
|
|
wantVal: nil,
|
|
wantErrMsg: "invalid option string \"24 dur 3y\": decoding dur: " +
|
|
"unmarshaling duration: time: unknown unit \"y\" in duration \"3y\"",
|
|
}, {
|
|
name: "u8_error",
|
|
in: "23 u8 256",
|
|
wantCode: nil,
|
|
wantVal: nil,
|
|
wantErrMsg: "invalid option string \"23 u8 256\": decoding u8: " +
|
|
"strconv.ParseUint: parsing \"256\": value out of range",
|
|
}, {
|
|
name: "u16_error",
|
|
in: "23 u16 65536",
|
|
wantCode: nil,
|
|
wantVal: nil,
|
|
wantErrMsg: "invalid option string \"23 u16 65536\": decoding u16: " +
|
|
"strconv.ParseUint: parsing \"65536\": value out of range",
|
|
}}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
code, val, err := parseDHCPOption(tc.in)
|
|
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
|
|
|
|
assert.Equal(t, tc.wantCode, code)
|
|
assert.Equal(t, tc.wantVal, val)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPrepareOptions(t *testing.T) {
|
|
oneIP, otherIP := net.IP{1, 2, 3, 4}, net.IP{5, 6, 7, 8}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
wantExplicit dhcpv4.Options
|
|
opts []string
|
|
}{{
|
|
name: "all_default",
|
|
wantExplicit: nil,
|
|
opts: nil,
|
|
}, {
|
|
name: "configured_ip",
|
|
wantExplicit: dhcpv4.OptionsFromList(
|
|
dhcpv4.OptBroadcastAddress(oneIP),
|
|
),
|
|
opts: []string{
|
|
fmt.Sprintf("%d ip %s", dhcpv4.OptionBroadcastAddress, oneIP),
|
|
},
|
|
}, {
|
|
name: "configured_ips",
|
|
wantExplicit: dhcpv4.OptionsFromList(
|
|
dhcpv4.Option{
|
|
Code: dhcpv4.OptionDomainNameServer,
|
|
Value: dhcpv4.IPs{oneIP, otherIP},
|
|
},
|
|
),
|
|
opts: []string{
|
|
fmt.Sprintf("%d ips %s,%s", dhcpv4.OptionDomainNameServer, oneIP, otherIP),
|
|
},
|
|
}, {
|
|
name: "configured_bad",
|
|
wantExplicit: nil,
|
|
opts: []string{
|
|
"19 bool yes",
|
|
"24 dur 3y",
|
|
"23 u8 256",
|
|
"23 u16 65536",
|
|
"20 hex",
|
|
"23 hex abc",
|
|
"32 ips 1,2,3,4",
|
|
"28 256.256.256.256",
|
|
},
|
|
}, {
|
|
name: "configured_del",
|
|
wantExplicit: dhcpv4.OptionsFromList(
|
|
dhcpv4.OptBroadcastAddress(nil),
|
|
),
|
|
opts: []string{
|
|
"28 del",
|
|
},
|
|
}, {
|
|
name: "rewritten_del",
|
|
wantExplicit: dhcpv4.OptionsFromList(
|
|
dhcpv4.OptBroadcastAddress(netutil.IPv4bcast()),
|
|
),
|
|
opts: []string{
|
|
"28 del",
|
|
"28 ip 255.255.255.255",
|
|
},
|
|
}, {
|
|
name: "configured_and_del",
|
|
wantExplicit: dhcpv4.OptionsFromList(
|
|
dhcpv4.Option{
|
|
Code: dhcpv4.OptionGeoConf,
|
|
Value: dhcpv4.String("cba"),
|
|
},
|
|
),
|
|
opts: []string{
|
|
"123 text abc",
|
|
"123 del",
|
|
"123 text cba",
|
|
},
|
|
}}
|
|
|
|
for _, tc := range testCases {
|
|
s := &v4Server{
|
|
conf: &V4ServerConf{
|
|
Options: tc.opts,
|
|
},
|
|
}
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
s.prepareOptions()
|
|
|
|
assert.Equal(t, tc.wantExplicit, s.explicitOpts)
|
|
|
|
for c := range s.explicitOpts {
|
|
assert.NotContains(t, s.implicitOpts, c)
|
|
}
|
|
})
|
|
}
|
|
}
|