mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
network/dhcp: several follow-ups for recent change (#39744)
Follow-ups for 7f9c0c31d2
This commit is contained in:
@@ -66,7 +66,8 @@ struct sd_dhcp_lease {
|
||||
|
||||
char *domainname;
|
||||
char **search_domains;
|
||||
char *hostname;
|
||||
char *hostname; /* SD_DHCP_OPTION_HOST_NAME (12) */
|
||||
char *fqdn; /* SD_DHCP_OPTION_FQDN (81) */
|
||||
char *root_path;
|
||||
char *captive_portal;
|
||||
|
||||
|
||||
@@ -199,10 +199,15 @@ int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(hostname, -EINVAL);
|
||||
|
||||
if (!lease->hostname)
|
||||
/* FQDN option (81) always takes precedence. */
|
||||
|
||||
if (lease->fqdn)
|
||||
*hostname = lease->fqdn;
|
||||
else if (lease->hostname)
|
||||
*hostname = lease->hostname;
|
||||
else
|
||||
return -ENODATA;
|
||||
|
||||
*hostname = lease->hostname;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -422,6 +427,7 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
|
||||
free(lease->router);
|
||||
free(lease->timezone);
|
||||
free(lease->hostname);
|
||||
free(lease->fqdn);
|
||||
free(lease->domainname);
|
||||
free(lease->captive_portal);
|
||||
|
||||
@@ -475,18 +481,18 @@ static int lease_parse_be32(const uint8_t *option, size_t len, be32_t *ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lease_parse_domain(const uint8_t *option, size_t len, char **ret) {
|
||||
static int lease_parse_domain(const uint8_t *option, size_t len, char **domain) {
|
||||
_cleanup_free_ char *name = NULL, *normalized = NULL;
|
||||
int r;
|
||||
|
||||
assert(option);
|
||||
assert(ret);
|
||||
assert(domain);
|
||||
|
||||
r = dhcp_option_parse_string(option, len, &name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (!name) {
|
||||
*ret = mfree(*ret);
|
||||
*domain = mfree(*domain);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -500,17 +506,15 @@ static int lease_parse_domain(const uint8_t *option, size_t len, char **ret) {
|
||||
if (dns_name_is_root(normalized))
|
||||
return -EINVAL;
|
||||
|
||||
free_and_replace(*ret, normalized);
|
||||
|
||||
return 0;
|
||||
return free_and_replace(*domain, normalized);
|
||||
}
|
||||
|
||||
static int lease_parse_fqdn(const uint8_t *option, size_t len, char **hostname) {
|
||||
static int lease_parse_fqdn(const uint8_t *option, size_t len, char **fqdn) {
|
||||
_cleanup_free_ char *name = NULL, *normalized = NULL;
|
||||
int r;
|
||||
|
||||
assert(option);
|
||||
assert(hostname);
|
||||
assert(fqdn);
|
||||
|
||||
/* RFC 4702 Section 2
|
||||
*
|
||||
@@ -540,7 +544,7 @@ static int lease_parse_fqdn(const uint8_t *option, size_t len, char **hostname)
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
*hostname = mfree(*hostname);
|
||||
*fqdn = mfree(*fqdn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -554,59 +558,52 @@ static int lease_parse_fqdn(const uint8_t *option, size_t len, char **hostname)
|
||||
if (dns_name_is_root(normalized))
|
||||
return -EINVAL;
|
||||
|
||||
free_and_replace(*hostname, normalized);
|
||||
|
||||
return 0;
|
||||
return free_and_replace(*fqdn, normalized);
|
||||
}
|
||||
|
||||
static int lease_parse_captive_portal(const uint8_t *option, size_t len, char **ret) {
|
||||
_cleanup_free_ char *uri = NULL;
|
||||
static int lease_parse_captive_portal(const uint8_t *option, size_t len, char **uri) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
int r;
|
||||
|
||||
assert(option);
|
||||
assert(ret);
|
||||
assert(uri);
|
||||
|
||||
r = dhcp_option_parse_string(option, len, &uri);
|
||||
r = dhcp_option_parse_string(option, len, &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (uri && !in_charset(uri, URI_VALID))
|
||||
if (s && !in_charset(s, URI_VALID))
|
||||
return -EINVAL;
|
||||
|
||||
return free_and_replace(*ret, uri);
|
||||
return free_and_replace(*uri, s);
|
||||
}
|
||||
|
||||
static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
|
||||
static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **addresses, size_t *n_addresses) {
|
||||
assert(option || len == 0);
|
||||
assert(ret);
|
||||
assert(n_ret);
|
||||
assert(addresses);
|
||||
assert(n_addresses);
|
||||
|
||||
if (len <= 0) {
|
||||
*ret = mfree(*ret);
|
||||
*n_ret = 0;
|
||||
} else {
|
||||
size_t n_addresses;
|
||||
struct in_addr *addresses;
|
||||
|
||||
if (len % 4 != 0)
|
||||
return -EINVAL;
|
||||
|
||||
n_addresses = len / 4;
|
||||
|
||||
addresses = newdup(struct in_addr, option, n_addresses);
|
||||
if (!addresses)
|
||||
return -ENOMEM;
|
||||
|
||||
free_and_replace(*ret, addresses);
|
||||
*n_ret = n_addresses;
|
||||
*n_addresses = 0;
|
||||
*addresses = mfree(*addresses);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (len % 4 != 0)
|
||||
return -EINVAL;
|
||||
|
||||
size_t n = len / 4;
|
||||
struct in_addr *a = newdup(struct in_addr, option, n);
|
||||
if (!a)
|
||||
return -ENOMEM;
|
||||
|
||||
*n_addresses = n;
|
||||
return free_and_replace(*addresses, a);
|
||||
}
|
||||
|
||||
static int lease_parse_sip_server(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
|
||||
static int lease_parse_sip_server(const uint8_t *option, size_t len, struct in_addr **sips, size_t *n_sips) {
|
||||
assert(option || len == 0);
|
||||
assert(ret);
|
||||
assert(n_ret);
|
||||
assert(sips);
|
||||
assert(n_sips);
|
||||
|
||||
if (len <= 0)
|
||||
return -EINVAL;
|
||||
@@ -616,12 +613,12 @@ static int lease_parse_sip_server(const uint8_t *option, size_t len, struct in_a
|
||||
* the other fields */
|
||||
|
||||
if (option[0] != 1) { /* We only support IP address encoding for now */
|
||||
*ret = mfree(*ret);
|
||||
*n_ret = 0;
|
||||
*sips = mfree(*sips);
|
||||
*n_sips = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return lease_parse_in_addrs(option + 1, len - 1, ret, n_ret);
|
||||
return lease_parse_in_addrs(option + 1, len - 1, sips, n_sips);
|
||||
}
|
||||
|
||||
static int lease_parse_dns_name(const uint8_t *optval, size_t optlen, char **ret) {
|
||||
@@ -641,14 +638,15 @@ static int lease_parse_dns_name(const uint8_t *optval, size_t optlen, char **ret
|
||||
return r;
|
||||
}
|
||||
|
||||
static int lease_parse_dnr(const uint8_t *option, size_t len, sd_dns_resolver **ret_dnr, size_t *ret_n_dnr) {
|
||||
static int lease_parse_dnr(const uint8_t *option, size_t len, sd_dns_resolver **dnr, size_t *n_dnr) {
|
||||
int r;
|
||||
sd_dns_resolver *res_list = NULL;
|
||||
size_t n_resolvers = 0;
|
||||
CLEANUP_ARRAY(res_list, n_resolvers, dns_resolver_done_many);
|
||||
|
||||
assert(option || len == 0);
|
||||
assert(ret_dnr);
|
||||
assert(dnr);
|
||||
assert(n_dnr);
|
||||
|
||||
_cleanup_(sd_dns_resolver_done) sd_dns_resolver res = {};
|
||||
|
||||
@@ -747,11 +745,11 @@ static int lease_parse_dnr(const uint8_t *option, size_t len, sd_dns_resolver **
|
||||
res_list[n_resolvers++] = TAKE_STRUCT(res);
|
||||
}
|
||||
|
||||
typesafe_qsort(*ret_dnr, *ret_n_dnr, dns_resolver_prio_compare);
|
||||
typesafe_qsort(res_list, n_resolvers, dns_resolver_prio_compare);
|
||||
|
||||
dns_resolver_done_many(*ret_dnr, *ret_n_dnr);
|
||||
*ret_dnr = TAKE_PTR(res_list);
|
||||
*ret_n_dnr = n_resolvers;
|
||||
dns_resolver_done_many(*dnr, *n_dnr);
|
||||
*dnr = TAKE_PTR(res_list);
|
||||
*n_dnr = n_resolvers;
|
||||
|
||||
return n_resolvers;
|
||||
}
|
||||
@@ -1021,12 +1019,6 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
|
||||
break;
|
||||
|
||||
case SD_DHCP_OPTION_HOST_NAME:
|
||||
/* FQDN option (81) always takes precedence. If it was already set, do not overwrite it. */
|
||||
if (lease->hostname) {
|
||||
log_debug("Hostname already set via FQDN, ignoring hostname option.");
|
||||
break;
|
||||
}
|
||||
|
||||
r = lease_parse_domain(option, len, &lease->hostname);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to parse hostname, ignoring: %m");
|
||||
@@ -1036,7 +1028,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
|
||||
break;
|
||||
|
||||
case SD_DHCP_OPTION_FQDN:
|
||||
r = lease_parse_fqdn(option, len, &lease->hostname);
|
||||
r = lease_parse_fqdn(option, len, &lease->fqdn);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to parse FQDN, ignoring: %m");
|
||||
return 0;
|
||||
|
||||
@@ -249,18 +249,8 @@ int config_parse_dhcp_static_lease_hostname(
|
||||
}
|
||||
|
||||
r = dns_name_is_valid_ldh(rvalue);
|
||||
if (r < 0)
|
||||
if (r <= 0)
|
||||
return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue);
|
||||
if (r == 0) {
|
||||
log_syntax(unit,
|
||||
LOG_WARNING,
|
||||
filename,
|
||||
line,
|
||||
0,
|
||||
"Invalid hostname for DHCPv4 static lease, ignoring assignment: %s",
|
||||
rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = free_and_strdup(&lease->hostname, rvalue);
|
||||
if (r < 0)
|
||||
|
||||
Reference in New Issue
Block a user