dhcp: add "static_key" argument to nm_dhcp_option_add_option() etc.

Our lease is tracked in a plain string dictionary. For dhclient plugin
and similar, the keys are received via the environment, they are thus
unlimited. For the internal plugins they are known at compile time and
static strings. We thus sometimes need to clone the string, and
sometimes not.

Unfortunately, we cannot ask the GHashTable whether it has a free
function for the key, so we need to explicitly tell it. Add a parameter
for that.
This commit is contained in:
Thomas Haller 2023-02-14 21:00:11 +01:00
parent e5dc489197
commit 5a05ba398b
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
5 changed files with 102 additions and 58 deletions

View file

@ -257,14 +257,11 @@ nm_dhcp_client_create_options_dict(NMDhcpClient *self, gboolean static_keys)
* may send the used client-id/DUID via the environment variables and
* overwrite them yet again. */
if (static_keys) {
nm_dhcp_option_add_option(options, priv->config.addr_family, option, str);
} else {
g_hash_table_insert(
options,
g_strdup(nm_dhcp_option_request_string(priv->config.addr_family, option)),
g_steal_pointer(&str));
}
nm_dhcp_option_take_option(options,
static_keys,
priv->config.addr_family,
option,
g_steal_pointer(&str));
}
return options;

View file

@ -84,6 +84,11 @@ static void dhcp4_event_pop_all_events_on_idle(NMDhcpNettools *self);
/*****************************************************************************/
#define _add_option(options, option, str) \
nm_dhcp_option_add_option((options), TRUE, AF_INET, (option), (str))
/*****************************************************************************/
static void
set_error_nettools(GError **error, int r, const char *message)
{
@ -266,26 +271,34 @@ lease_parse_address(NMDhcpNettools *self /* for logging context only */,
}
nm_dhcp_option_add_option_in_addr(options,
TRUE,
AF_INET,
NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS,
a_address.s_addr);
nm_dhcp_option_add_option_in_addr(options,
TRUE,
AF_INET,
NM_DHCP_OPTION_DHCP4_SUBNET_MASK,
a_netmask);
nm_dhcp_option_add_option_u64(options,
TRUE,
AF_INET,
NM_DHCP_OPTION_DHCP4_IP_ADDRESS_LEASE_TIME,
(guint64) a_lifetime);
if (a_expiry != G_MAXUINT64) {
nm_dhcp_option_add_option_u64(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_EXPIRY, a_expiry);
nm_dhcp_option_add_option_u64(options,
TRUE,
AF_INET,
NM_DHCP_OPTION_DHCP4_NM_EXPIRY,
a_expiry);
}
n_dhcp4_client_lease_get_siaddr(lease, &a_next_server);
if (a_next_server.s_addr != INADDR_ANY) {
nm_dhcp_option_add_option_in_addr(options,
TRUE,
AF_INET,
NM_DHCP_OPTION_DHCP4_NM_NEXT_SERVER,
a_next_server.s_addr);
@ -368,7 +381,7 @@ lease_parse_address_list(NDhcp4ClientLease *lease,
}
}
nm_dhcp_option_add_option(options, AF_INET, option, nm_str_buf_get_str(sbuf));
_add_option(options, option, nm_str_buf_get_str(sbuf));
}
static void
@ -446,7 +459,7 @@ lease_parse_routes(NDhcp4ClientLease *lease,
}
has_classless = TRUE;
nm_dhcp_option_add_option(options, AF_INET, option_code, nm_str_buf_get_str(sbuf));
_add_option(options, option_code, nm_str_buf_get_str(sbuf));
}
r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, &l_data, &l_data_len);
@ -489,10 +502,7 @@ lease_parse_routes(NDhcp4ClientLease *lease,
}));
}
nm_dhcp_option_add_option(options,
AF_INET,
NM_DHCP_OPTION_DHCP4_STATIC_ROUTE,
nm_str_buf_get_str(sbuf));
_add_option(options, NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, nm_str_buf_get_str(sbuf));
}
r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_ROUTER, &l_data, &l_data_len);
@ -534,10 +544,7 @@ lease_parse_routes(NDhcp4ClientLease *lease,
}));
}
nm_dhcp_option_add_option(options,
AF_INET,
NM_DHCP_OPTION_DHCP4_ROUTER,
nm_str_buf_get_str(sbuf));
_add_option(options, NM_DHCP_OPTION_DHCP4_ROUTER, nm_str_buf_get_str(sbuf));
}
}
@ -570,6 +577,7 @@ lease_parse_search_domains(NDhcp4ClientLease *lease,
nm_l3_config_data_add_search(l3cd, AF_INET, domains[i]);
nm_dhcp_option_take_option(options,
TRUE,
AF_INET,
NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST,
g_strjoinv(" ", domains));
@ -598,7 +606,7 @@ lease_parse_private_options(NDhcp4ClientLease *lease, GHashTable *options)
continue;
option_string = nm_utils_bin2hexstr_full(l_data, l_data_len, ':', FALSE, NULL);
nm_dhcp_option_take_option(options, AF_INET, i, g_steal_pointer(&option_string));
nm_dhcp_option_take_option(options, TRUE, AF_INET, i, g_steal_pointer(&option_string));
}
}
@ -632,6 +640,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err
r = n_dhcp4_client_lease_get_server_identifier(lease, &v_inaddr_s);
if (r == 0) {
nm_dhcp_option_add_option_in_addr(options,
TRUE,
AF_INET,
NM_DHCP_OPTION_DHCP4_SERVER_ID,
v_inaddr_s.s_addr);
@ -645,6 +654,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err
iface,
NM_DHCP_OPTION_DHCP4_BROADCAST)) {
nm_dhcp_option_add_option_in_addr(options,
TRUE,
AF_INET,
NM_DHCP_OPTION_DHCP4_BROADCAST,
v_inaddr);
@ -696,10 +706,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err
}
if (sbuf.len > 0) {
nm_dhcp_option_add_option(options,
AF_INET,
NM_DHCP_OPTION_DHCP4_DOMAIN_NAME,
nm_str_buf_get_str(&sbuf));
_add_option(options, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME, nm_str_buf_get_str(&sbuf));
}
}
@ -713,7 +720,11 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err
iface,
AF_INET,
NM_DHCP_OPTION_DHCP4_INTERFACE_MTU)) {
nm_dhcp_option_add_option_u64(options, AF_INET, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, v_u16);
nm_dhcp_option_add_option_u64(options,
TRUE,
AF_INET,
NM_DHCP_OPTION_DHCP4_INTERFACE_MTU,
v_u16);
nm_l3_config_data_set_mtu(l3cd, v_u16);
}
@ -731,7 +742,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err
iface,
AF_INET,
NM_DHCP_OPTION_DHCP4_HOST_NAME)) {
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_HOST_NAME, s);
_add_option(options, NM_DHCP_OPTION_DHCP4_HOST_NAME, s);
}
}
@ -755,6 +766,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err
/* "Its minimum length is 1." */
} else {
nm_dhcp_option_add_option_utf8safe_escape(options,
TRUE,
AF_INET,
NM_DHCP_OPTION_DHCP4_ROOT_PATH,
l_data,
@ -782,10 +794,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err
const char *escaped;
escaped = nm_utils_buf_utf8safe_escape((char *) l_data, l_data_len, 0, &to_free);
nm_dhcp_option_add_option(options,
AF_INET,
NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY,
escaped ?: "");
_add_option(options, NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY, escaped ?: "");
nm_l3_config_data_set_proxy_method(l3cd, NM_PROXY_CONFIG_METHOD_AUTO);
nm_l3_config_data_set_proxy_pac_url(l3cd, escaped ?: "");
@ -808,7 +817,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL,
&to_free);
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, v_str ?: "");
_add_option(options, NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, v_str ?: "");
nm_l3_config_data_set_nis_domain(l3cd, v_str ?: "");
}
@ -820,7 +829,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err
-1,
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL,
&to_free);
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_FILENAME, v_str ?: "");
_add_option(options, NM_DHCP_OPTION_DHCP4_NM_FILENAME, v_str ?: "");
}
r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME, &l_data, &l_data_len);
@ -837,10 +846,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err
l_data_len,
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL,
&to_free);
nm_dhcp_option_add_option(options,
AF_INET,
NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME,
v_str ?: "");
_add_option(options, NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME, v_str ?: "");
}
lease_parse_address_list(lease, l3cd, iface, NM_DHCP_OPTION_DHCP4_NIS_SERVERS, options, &sbuf);

View file

@ -383,8 +383,14 @@ nm_dhcp_option_find(int addr_family, guint option)
/*****************************************************************************/
void
nm_dhcp_option_take_option(GHashTable *options, int addr_family, guint option, char *value)
nm_dhcp_option_take_option(GHashTable *options,
gboolean static_keys,
int addr_family,
guint option,
char *value)
{
const char *key;
nm_assert_addr_family(addr_family);
nm_assert(value);
nm_assert(g_utf8_validate(value, -1, NULL));
@ -395,19 +401,13 @@ nm_dhcp_option_take_option(GHashTable *options, int addr_family, guint option, c
return;
}
g_hash_table_insert(options,
(gpointer) nm_dhcp_option_request_string(addr_family, option),
value);
}
void
nm_dhcp_option_add_option(GHashTable *options, int addr_family, guint option, const char *value)
{
nm_dhcp_option_take_option(options, addr_family, option, g_strdup(value));
key = nm_dhcp_option_request_string(addr_family, option),
g_hash_table_insert(options, static_keys ? (gpointer) key : g_strdup(key), value);
}
void
nm_dhcp_option_add_option_utf8safe_escape(GHashTable *options,
gboolean static_keys,
int addr_family,
guint option,
const guint8 *data,
@ -420,13 +420,18 @@ nm_dhcp_option_add_option_utf8safe_escape(GHashTable *options,
n_data,
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL,
&to_free);
nm_dhcp_option_add_option(options, addr_family, option, escaped ?: "");
nm_dhcp_option_add_option(options, static_keys, addr_family, option, escaped ?: "");
}
void
nm_dhcp_option_add_option_u64(GHashTable *options, int addr_family, guint option, guint64 value)
nm_dhcp_option_add_option_u64(GHashTable *options,
gboolean static_keys,
int addr_family,
guint option,
guint64 value)
{
nm_dhcp_option_take_option(options,
static_keys,
addr_family,
option,
g_strdup_printf("%" G_GUINT64_FORMAT, value));
@ -434,13 +439,18 @@ nm_dhcp_option_add_option_u64(GHashTable *options, int addr_family, guint option
void
nm_dhcp_option_add_option_in_addr(GHashTable *options,
gboolean static_keys,
int addr_family,
guint option,
in_addr_t value)
{
char sbuf[NM_INET_ADDRSTRLEN];
nm_dhcp_option_add_option(options, addr_family, option, nm_inet4_ntop(value, sbuf));
nm_dhcp_option_add_option(options,
static_keys,
addr_family,
option,
nm_inet4_ntop(value, sbuf));
}
void

View file

@ -208,20 +208,38 @@ nm_dhcp_option_request_string(int addr_family, guint option)
return nm_dhcp_option_get_name(nm_dhcp_option_find(addr_family, option));
}
void nm_dhcp_option_take_option(GHashTable *options, int addr_family, guint option, char *value);
void
nm_dhcp_option_add_option(GHashTable *options, int addr_family, guint option, const char *value);
void nm_dhcp_option_take_option(GHashTable *options,
gboolean static_keys,
int addr_family,
guint option,
char *value);
static inline void
nm_dhcp_option_add_option(GHashTable *options,
gboolean static_keys,
int addr_family,
guint option,
const char *value)
{
nm_dhcp_option_take_option(options, static_keys, addr_family, option, g_strdup(value));
}
void nm_dhcp_option_add_option_utf8safe_escape(GHashTable *options,
gboolean static_keys,
int addr_family,
guint option,
const guint8 *data,
gsize n_data);
void nm_dhcp_option_add_option_in_addr(GHashTable *options,
gboolean static_keys,
int addr_family,
guint option,
in_addr_t value);
void
nm_dhcp_option_add_option_u64(GHashTable *options, int addr_family, guint option, guint64 value);
void nm_dhcp_option_add_option_u64(GHashTable *options,
gboolean static_keys,
int addr_family,
guint option,
guint64 value);
void nm_dhcp_option_add_requests_to_options(GHashTable *options, int addr_family);
GHashTable *nm_dhcp_option_create_options_dict(gboolean static_keys);

View file

@ -115,6 +115,7 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro
if (str->len) {
nm_dhcp_option_add_option(options,
TRUE,
AF_INET6,
NM_DHCP_OPTION_DHCP6_NM_IP_ADDRESS,
str->str);
@ -137,7 +138,11 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro
g_string_append(nm_gstring_add_space_delimiter(str), addr_str);
nm_l3_config_data_add_nameserver_detail(l3cd, AF_INET6, &dns[i], NULL);
}
nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_DNS_SERVERS, str->str);
nm_dhcp_option_add_option(options,
TRUE,
AF_INET6,
NM_DHCP_OPTION_DHCP6_DNS_SERVERS,
str->str);
}
num = sd_dhcp6_lease_get_domains(lease, &domains);
@ -147,11 +152,15 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro
g_string_append(nm_gstring_add_space_delimiter(str), domains[i]);
nm_l3_config_data_add_search(l3cd, AF_INET6, domains[i]);
}
nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_DOMAIN_LIST, str->str);
nm_dhcp_option_add_option(options,
TRUE,
AF_INET6,
NM_DHCP_OPTION_DHCP6_DOMAIN_LIST,
str->str);
}
if (sd_dhcp6_lease_get_fqdn(lease, &s) >= 0) {
nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_FQDN, s);
nm_dhcp_option_add_option(options, TRUE, AF_INET6, NM_DHCP_OPTION_DHCP6_FQDN, s);
}
/* RFC 5908, section 4 states: "This option MUST include one, and only
@ -175,7 +184,11 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro
}
}
if (str->len) {
nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_NTP_SERVER, str->str);
nm_dhcp_option_add_option(options,
TRUE,
AF_INET6,
NM_DHCP_OPTION_DHCP6_NTP_SERVER,
str->str);
}
nm_l3_config_data_set_dhcp_lease_from_options(l3cd, AF_INET6, g_steal_pointer(&options));