mirror of
https://github.com/systemd/systemd.git
synced 2025-03-22 06:50:18 +03:00
dns-domain: accept encoded domain names without terminating zero label
Commit 1be9b30a3b17 ("dhcp6: use dns_name_from_wire_format") introduced a stricter validation of domains received via DHCPv6, by using function dns_name_from_wire_format() which rejects the domain when it is missing the terminating zero label. According to RFC 4704 § 4.2, DHCPv6 servers should always add the zero label: To send a fully qualified domain name, the Domain Name field is set to the DNS-encoded domain name including the terminating zero-length label. To send a partial name, the Domain Name field is set to the DNS-encoded domain name without the terminating zero-length label. [...] Servers SHOULD send the complete fully qualified domain name in Client FQDN options. In practice, there is at least on common DHCPv6 server implementation (dnsmasq) that sends the FQDN option without the ending zero-length label; after upgrading to the new systemd, the client cannot parse the option and therefore the machine doesn't get the hostname provided by dnsmasq. This commit restores the old behavior that considers a domain valid even when it's missing the terminating zero label. Here's a quick reproducer: --8<-- ip link add veth0 type veth peer name veth1 ip netns add ns1 ip link set veth1 netns ns1 ip link set veth0 address 00:11:22:33:44:55 ip link set veth0 up ip -n ns1 link set veth1 up ip -n ns1 address add dev veth1 fd01::1/64 ip netns exec ns1 dnsmasq \ --pid-file=/tmp/dnsmasq.pid --no-hosts \ --bind-interfaces --interface veth1 --except-interface lo \ --dhcp-range=fd01::100,fd01::200 --enable-ra \ --dhcp-host 00:11:22:33:44:55,foobar & cat <<EOF > /etc/systemd/network/veth0.network [Match] Name=veth0 [Network] DHCP=ipv6 EOF networkctl reload networkctl up veth0 sleep 5 hostname --8<-- Without this change, systemd-networkd prints the following message and doesn't set the hostname from DHCP: veth0: DHCPv6 client: Failed to parse FQDN option, ignoring: Bad message
This commit is contained in:
parent
515ab90e4d
commit
30675a6ee9
@ -165,7 +165,9 @@ TEST(parse_domain) {
|
||||
domain = mfree(domain);
|
||||
|
||||
data = (uint8_t []) { 4, 't', 'e', 's', 't' };
|
||||
assert_se(dhcp6_option_parse_domainname(data, 5, &domain) < 0);
|
||||
ASSERT_OK(dhcp6_option_parse_domainname(data, 5, &domain));
|
||||
ASSERT_STREQ(domain, "test");
|
||||
domain = mfree(domain);
|
||||
|
||||
data = (uint8_t []) { 0 };
|
||||
assert_se(dhcp6_option_parse_domainname(data, 1, &domain) < 0);
|
||||
|
@ -924,9 +924,12 @@ int dns_name_from_wire_format(const uint8_t **data, size_t *len, char **ret) {
|
||||
const char *label;
|
||||
uint8_t c;
|
||||
|
||||
/* Unterminated name */
|
||||
/* RFC 4704 § 4: fully qualified domain names include the terminating
|
||||
* zero-length label, partial names don't. According to the RFC, DHCPv6
|
||||
* servers should always send the fully qualified name, but that's not
|
||||
* true in practice. Also accept partial names. */
|
||||
if (optlen == 0)
|
||||
return -EBADMSG;
|
||||
break;
|
||||
|
||||
/* RFC 1035 § 3.1 total length of encoded name is limited to 255 octets */
|
||||
if (*len - optlen > 255)
|
||||
|
@ -197,7 +197,7 @@ TEST(dns_name_from_wire_format) {
|
||||
test_dns_name_from_wire_format_one("", in0, sizeof(in0), strlen(""));
|
||||
|
||||
test_dns_name_from_wire_format_one("foo", in1, sizeof(in1), strlen("foo"));
|
||||
test_dns_name_from_wire_format_one(NULL, in1, sizeof(in1) - 1, -EBADMSG);
|
||||
test_dns_name_from_wire_format_one("foo", in1, sizeof(in1) - 1, strlen("foo"));
|
||||
|
||||
test_dns_name_from_wire_format_one("hallo.foo.bar", in2, sizeof(in2), strlen("hallo.foo.bar"));
|
||||
test_dns_name_from_wire_format_one("hallo.foo", in2_1, sizeof(in2_1), strlen("hallo.foo"));
|
||||
|
Loading…
x
Reference in New Issue
Block a user