forked from bottlerocket-os/bottlerocket
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request bottlerocket-os#3416 from bcressey/resolved-to-par…
…se-domains support non-standard DHCP Option 15 in EC2
- Loading branch information
Showing
2 changed files
with
135 additions
and
0 deletions.
There are no files selected for viewing
131 changes: 131 additions & 0 deletions
131
packages/systemd/9013-sd-dhcp-lease-parse-multiple-domains-in-option-15.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
From 4c79d11d6888944f251681003a7b8b41606e108b Mon Sep 17 00:00:00 2001 | ||
From: Ben Cressey <[email protected]> | ||
Date: Sat, 2 Sep 2023 16:19:22 +0000 | ||
Subject: [PATCH] sd-dhcp-lease: parse multiple domains in option 15 | ||
|
||
Non-compliant DHCP servers may pass through multiple domain names in | ||
Option 15, separated by a space character. This is then normalized | ||
into "032" by systemd-networkd, which effectively synthesizes a new | ||
domain name that doesn't match any of the expected ones. | ||
|
||
DHCP also supports Option 119 which specifies a compression scheme to | ||
avoid repeating any shared suffixes of the domain names. This option | ||
doesn't support space-separated domains either, so working around the | ||
problem isn't as straightforward as treating an Option 15 payload as | ||
a 119 payload instead. | ||
|
||
Deal with this by splitting the Option 15 payload on spaces first, | ||
before normalizing the individual domain names. If multiple domains | ||
are found, use them as the list of search domains unless Option 119 | ||
is also present. | ||
|
||
Signed-off-by: Ben Cressey <[email protected]> | ||
--- | ||
src/libsystemd-network/sd-dhcp-lease.c | 69 +++++++++++++++++++++----- | ||
1 file changed, 56 insertions(+), 13 deletions(-) | ||
|
||
diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c | ||
index b14ad57..263e97e 100644 | ||
--- a/src/libsystemd-network/sd-dhcp-lease.c | ||
+++ b/src/libsystemd-network/sd-dhcp-lease.c | ||
@@ -401,34 +401,70 @@ static int lease_parse_string(const uint8_t *option, size_t len, char **ret) { | ||
return 0; | ||
} | ||
|
||
-static int lease_parse_domain(const uint8_t *option, size_t len, char **ret) { | ||
- _cleanup_free_ char *name = NULL, *normalized = NULL; | ||
+static int lease_parse_domain_list(const uint8_t *option, size_t len, char ***ret) { | ||
+ _cleanup_free_ char *parsed = NULL; | ||
+ _cleanup_strv_free_ char **names = NULL, **normalized_names = NULL; | ||
int r; | ||
|
||
assert(option); | ||
assert(ret); | ||
|
||
- r = lease_parse_string(option, len, &name); | ||
+ r = lease_parse_string(option, len, &parsed); | ||
if (r < 0) | ||
return r; | ||
- if (!name) { | ||
- *ret = mfree(*ret); | ||
+ | ||
+ if (!parsed) | ||
return 0; | ||
+ | ||
+ names = strv_split(parsed, " "); | ||
+ if (!names) | ||
+ return -ENOMEM; | ||
+ | ||
+ STRV_FOREACH(name, names) { | ||
+ _cleanup_free_ char *normalized = NULL; | ||
+ | ||
+ r = dns_name_normalize(*name, 0, &normalized); | ||
+ if (r < 0) | ||
+ return r; | ||
+ | ||
+ if (is_localhost(normalized)) | ||
+ return -EINVAL; | ||
+ | ||
+ if (dns_name_is_root(normalized)) | ||
+ return -EINVAL; | ||
+ | ||
+ r = strv_extend(&normalized_names, normalized); | ||
+ if (r < 0) | ||
+ return r; | ||
} | ||
|
||
- r = dns_name_normalize(name, 0, &normalized); | ||
+ strv_free_and_replace(*ret, normalized_names); | ||
+ return 0; | ||
+} | ||
+ | ||
+static int lease_parse_domain(const uint8_t *option, size_t len, char **ret) { | ||
+ _cleanup_strv_free_ char **names = NULL; | ||
+ size_t n; | ||
+ int r; | ||
+ | ||
+ assert(option); | ||
+ assert(ret); | ||
+ | ||
+ r = lease_parse_domain_list(option, len, &names); | ||
if (r < 0) | ||
return r; | ||
|
||
- if (is_localhost(normalized)) | ||
- return -EINVAL; | ||
- | ||
- if (dns_name_is_root(normalized)) | ||
- return -EINVAL; | ||
+ n = strv_length(names); | ||
+ if (n == 0) { | ||
+ *ret = mfree(*ret); | ||
+ return 0; | ||
+ } | ||
|
||
- free_and_replace(*ret, normalized); | ||
+ r = free_and_strdup(ret, names[0]); | ||
+ if (r < 0) | ||
+ return r; | ||
|
||
- return 0; | ||
+ return n; | ||
} | ||
|
||
static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) { | ||
@@ -725,6 +761,13 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void | ||
return 0; | ||
} | ||
|
||
+ if (r <= 1 || !strv_isempty(lease->search_domains)) | ||
+ break; | ||
+ | ||
+ r = lease_parse_domain_list(option, len, &lease->search_domains); | ||
+ if (r < 0) | ||
+ log_debug_errno(r, "Failed to parse Domain Search List, ignoring: %m"); | ||
+ | ||
break; | ||
|
||
case SD_DHCP_OPTION_DOMAIN_SEARCH: | ||
-- | ||
2.40.1 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters