diff options
| author | Michael Biebl <biebl@debian.org> | 2022-10-04 00:56:46 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2022-10-04 00:56:46 +0200 |
| commit | 3612e6355f3f40d264ec4657547761069baa5430 (patch) | |
| tree | 768e4f5b37b66f540dd7030aa2eaff2ac7bb0168 /src/core/dhcp/nm-dhcp-nettools.c | |
| parent | 7e9f00a3be8f65535e6620b344443ec4d403212b (diff) | |
| parent | 6f7fcde10e47d8af865af336becf1fd8a446e62e (diff) | |
Merge tag 'debian/1.40.0-1' into debian/bullseye-backports
network-manager Debian release 1.40.0-1
Diffstat (limited to 'src/core/dhcp/nm-dhcp-nettools.c')
| -rw-r--r-- | src/core/dhcp/nm-dhcp-nettools.c | 315 |
1 files changed, 243 insertions, 72 deletions
diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c index 2e41cf15..05b7b52e 100644 --- a/src/core/dhcp/nm-dhcp-nettools.c +++ b/src/core/dhcp/nm-dhcp-nettools.c @@ -13,22 +13,24 @@ #include <ctype.h> #include <net/if_arp.h> +#include "n-dhcp4/src/n-dhcp4.h" + #include "libnm-glib-aux/nm-dedup-multi.h" -#include "libnm-std-aux/unaligned.h" +#include "libnm-glib-aux/nm-io-utils.h" #include "libnm-glib-aux/nm-str-buf.h" +#include "libnm-std-aux/unaligned.h" -#include "nm-l3-config-data.h" -#include "nm-utils.h" -#include "nm-config.h" -#include "nm-dhcp-utils.h" -#include "nm-dhcp-options.h" -#include "nm-core-utils.h" #include "NetworkManagerUtils.h" #include "libnm-platform/nm-platform.h" +#include "nm-config.h" +#include "nm-core-utils.h" #include "nm-dhcp-client-logging.h" -#include "n-dhcp4/src/n-dhcp4.h" +#include "nm-dhcp-options.h" +#include "nm-dhcp-utils.h" +#include "nm-l3-config-data.h" +#include "nm-utils.h" + #include "libnm-systemd-shared/nm-sd-utils-shared.h" -#include "libnm-systemd-core/nm-sd-utils-dhcp.h" /*****************************************************************************/ @@ -56,6 +58,8 @@ typedef struct { const NML3ConfigData *lease_l3cd; } granted; + GSource *pop_all_events_on_idle_source; + GSource *event_source; char *lease_file; } NMDhcpNettoolsPrivate; @@ -76,6 +80,10 @@ G_DEFINE_TYPE(NMDhcpNettools, nm_dhcp_nettools, NM_TYPE_DHCP_CLIENT) /*****************************************************************************/ +static void dhcp4_event_pop_all_events_on_idle(NMDhcpNettools *self); + +/*****************************************************************************/ + static void set_error_nettools(GError **error, int r, const char *message) { @@ -156,8 +164,10 @@ lease_option_consume_route(const uint8_t **datap, /*****************************************************************************/ static gboolean -lease_parse_address(NDhcp4ClientLease *lease, +lease_parse_address(NMDhcpNettools *self /* for logging context only */, + NDhcp4ClientLease *lease, NML3ConfigData *l3cd, + const char *iface, GHashTable *options, in_addr_t *out_address, GError **error) @@ -228,15 +238,33 @@ lease_parse_address(NDhcp4ClientLease *lease, } r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_SUBNET_MASK, &l_data, &l_data_len); - if (r != 0 || !nm_dhcp_lease_data_parse_in_addr(l_data, l_data_len, &a_netmask)) { - nm_utils_error_set_literal(error, - NM_UTILS_ERROR_UNKNOWN, - "could not get netmask from lease"); - return FALSE; + if (r == N_DHCP4_E_UNSET) { + char str1[NM_UTILS_INET_ADDRSTRLEN]; + char str2[NM_UTILS_INET_ADDRSTRLEN]; + + /* Some DHCP servers may not set the subnet-mask (issue#1037). + * Do the same as the dhclient plugin and use a default. */ + a_plen = _nm_utils_ip4_get_default_prefix(a_address.s_addr); + a_netmask = _nm_utils_ip4_prefix_to_netmask(a_plen); + _LOGT("missing subnet mask (option 1). Guess %s based on IP address %s", + _nm_utils_inet4_ntop(a_netmask, str1), + _nm_utils_inet4_ntop(a_address.s_addr, str2)); + } else { + if (r != 0 + || !nm_dhcp_lease_data_parse_in_addr(l_data, + l_data_len, + &a_netmask, + iface, + NM_DHCP_OPTION_DHCP4_SUBNET_MASK)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_UNKNOWN, + "could not get netmask from lease"); + return FALSE; + } + a_plen = _nm_utils_ip4_netmask_to_prefix(a_netmask); + a_netmask = _nm_utils_ip4_prefix_to_netmask(a_plen); } - a_plen = nm_utils_ip4_netmask_to_prefix(a_netmask); - nm_dhcp_option_add_option_in_addr(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS, @@ -282,6 +310,7 @@ lease_parse_address(NDhcp4ClientLease *lease, static void lease_parse_address_list(NDhcp4ClientLease *lease, NML3ConfigData *l3cd, + const char *iface, NMDhcpOptionDhcp4Options option, GHashTable *options, NMStrBuf *sbuf) @@ -294,8 +323,14 @@ lease_parse_address_list(NDhcp4ClientLease *lease, if (r != 0) return; - if (l_data_len == 0 || l_data_len % 4 != 0) + if (l_data_len == 0 || l_data_len % 4 != 0) { + nm_dhcp_lease_log_invalid_option(iface, + AF_INET, + option, + "wrong option length %lu", + (unsigned long) l_data_len); return; + } nm_str_buf_reset(sbuf); @@ -308,9 +343,14 @@ lease_parse_address_list(NDhcp4ClientLease *lease, switch (option) { case NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER: - if (addr == 0 || nm_ip4_addr_is_localhost(addr)) { + if (addr == 0 || nm_utils_ip4_address_is_loopback(addr)) { /* Skip localhost addresses, like also networkd does. * See https://github.com/systemd/systemd/issues/4524. */ + nm_dhcp_lease_log_invalid_option(iface, + AF_INET, + option, + "address %s is ignored", + _nm_utils_inet4_ntop(addr, addr_str)); continue; } nm_l3_config_data_add_nameserver(l3cd, AF_INET, &addr); @@ -502,7 +542,10 @@ lease_parse_routes(NDhcp4ClientLease *lease, } static void -lease_parse_search_domains(NDhcp4ClientLease *lease, NML3ConfigData *l3cd, GHashTable *options) +lease_parse_search_domains(NDhcp4ClientLease *lease, + NML3ConfigData *l3cd, + const char *iface, + GHashTable *options) { gs_strfreev char **domains = NULL; const guint8 *l_data; @@ -514,7 +557,11 @@ lease_parse_search_domains(NDhcp4ClientLease *lease, NML3ConfigData *l3cd, GHash if (r != 0) return; - domains = nm_dhcp_lease_data_parse_search_list(l_data, l_data_len); + domains = nm_dhcp_lease_data_parse_search_list(l_data, + l_data_len, + iface, + AF_INET, + NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST); if (!domains || !domains[0]) return; @@ -556,12 +603,9 @@ lease_parse_private_options(NDhcp4ClientLease *lease, GHashTable *options) } static NML3ConfigData * -lease_to_ip4_config(NMDedupMultiIndex *multi_idx, - const char *iface, - int ifindex, - NDhcp4ClientLease *lease, - GError **error) +lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **error) { + const char *iface; nm_auto_str_buf NMStrBuf sbuf = NM_STR_BUF_INIT(0, FALSE); nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL; gs_unref_hashtable GHashTable *options = NULL; @@ -574,13 +618,15 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, struct in_addr v_inaddr_s; int r; - g_return_val_if_fail(lease != NULL, NULL); + nm_assert(lease); + + iface = nm_dhcp_client_get_iface(NM_DHCP_CLIENT(self)); - l3cd = nm_l3_config_data_new(multi_idx, ifindex, NM_IP_CONFIG_SOURCE_DHCP); + l3cd = nm_dhcp_client_create_l3cd(NM_DHCP_CLIENT(self)); options = nm_dhcp_option_create_options_dict(); - if (!lease_parse_address(lease, l3cd, options, &lease_address, error)) + if (!lease_parse_address(self, lease, l3cd, iface, options, &lease_address, error)) return NULL; r = n_dhcp4_client_lease_get_server_identifier(lease, &v_inaddr_s); @@ -592,7 +638,12 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, } r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_BROADCAST, &l_data, &l_data_len); - if (r == 0 && nm_dhcp_lease_data_parse_in_addr(l_data, l_data_len, &v_inaddr)) { + if (r == 0 + && nm_dhcp_lease_data_parse_in_addr(l_data, + l_data_len, + &v_inaddr, + iface, + NM_DHCP_OPTION_DHCP4_BROADCAST)) { nm_dhcp_option_add_option_in_addr(options, AF_INET, NM_DHCP_OPTION_DHCP4_BROADCAST, @@ -601,10 +652,21 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, lease_parse_routes(lease, l3cd, lease_address, options, &sbuf); - lease_parse_address_list(lease, l3cd, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER, options, &sbuf); + lease_parse_address_list(lease, + l3cd, + iface, + NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER, + options, + &sbuf); r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME, &l_data, &l_data_len); - if (r == 0 && nm_dhcp_lease_data_parse_cstr(l_data, l_data_len, &l_data_len)) { + if (r == 0 + && nm_dhcp_lease_data_parse_cstr(l_data, + l_data_len, + &l_data_len, + iface, + AF_INET, + NM_DHCP_OPTION_DHCP4_DOMAIN_NAME)) { gs_free const char **domains = NULL; nm_str_buf_reset(&sbuf); @@ -620,7 +682,10 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, for (i = 0; domains[i]; i++) { gs_free char *s = NULL; - s = nm_dhcp_lease_data_parse_domain_validate(domains[i]); + s = nm_dhcp_lease_data_parse_domain_validate(domains[i], + iface, + AF_INET, + NM_DHCP_OPTION_DHCP4_DOMAIN_NAME); if (!s) continue; @@ -638,10 +703,16 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, } } - lease_parse_search_domains(lease, l3cd, options); + lease_parse_search_domains(lease, l3cd, iface, options); r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, &l_data, &l_data_len); - if (r == 0 && nm_dhcp_lease_data_parse_mtu(l_data, l_data_len, &v_u16)) { + if (r == 0 + && nm_dhcp_lease_data_parse_mtu(l_data, + l_data_len, + &v_u16, + 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_l3_config_data_set_mtu(l3cd, v_u16); } @@ -654,15 +725,26 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, if (r == 0) { gs_free char *s = NULL; - if (nm_dhcp_lease_data_parse_domain(l_data, l_data_len, &s)) { + if (nm_dhcp_lease_data_parse_domain(l_data, + l_data_len, + &s, + iface, + AF_INET, + NM_DHCP_OPTION_DHCP4_HOST_NAME)) { nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_HOST_NAME, s); } } - lease_parse_address_list(lease, l3cd, NM_DHCP_OPTION_DHCP4_NTP_SERVER, options, &sbuf); + lease_parse_address_list(lease, l3cd, iface, NM_DHCP_OPTION_DHCP4_NTP_SERVER, options, &sbuf); r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_ROOT_PATH, &l_data, &l_data_len); - if (r == 0 && nm_dhcp_lease_data_parse_cstr(l_data, l_data_len, &l_data_len)) { + if (r == 0 + && nm_dhcp_lease_data_parse_cstr(l_data, + l_data_len, + &l_data_len, + iface, + AF_INET, + NM_DHCP_OPTION_DHCP4_ROOT_PATH)) { /* https://tools.ietf.org/html/rfc2132#section-3.19 * * The path is formatted as a character string consisting of @@ -684,7 +766,13 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY, &l_data, &l_data_len); - if (r == 0 && nm_dhcp_lease_data_parse_cstr(l_data, l_data_len, &l_data_len)) { + if (r == 0 + && nm_dhcp_lease_data_parse_cstr(l_data, + l_data_len, + &l_data_len, + iface, + AF_INET, + NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY)) { /* https://tools.ietf.org/html/draft-ietf-wrec-wpad-01#section-4.4.1 * * We reject NUL characters inside the string (except trailing NULs). @@ -704,7 +792,13 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, } r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, &l_data, &l_data_len); - if (r == 0 && nm_dhcp_lease_data_parse_cstr(l_data, l_data_len, &l_data_len)) { + if (r == 0 + && nm_dhcp_lease_data_parse_cstr(l_data, + l_data_len, + &l_data_len, + iface, + AF_INET, + NM_DHCP_OPTION_DHCP4_NIS_DOMAIN)) { gs_free char *to_free = NULL; /* https://tools.ietf.org/html/rfc2132#section-8.1 */ @@ -730,7 +824,13 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, } r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME, &l_data, &l_data_len); - if (r == 0 && nm_dhcp_lease_data_parse_cstr(l_data, l_data_len, &l_data_len)) { + if (r == 0 + && nm_dhcp_lease_data_parse_cstr(l_data, + l_data_len, + &l_data_len, + iface, + AF_INET, + NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME)) { gs_free char *to_free = NULL; v_str = nm_utils_buf_utf8safe_escape((char *) l_data, @@ -743,9 +843,14 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, v_str ?: ""); } - lease_parse_address_list(lease, l3cd, NM_DHCP_OPTION_DHCP4_NIS_SERVERS, options, &sbuf); + lease_parse_address_list(lease, l3cd, iface, NM_DHCP_OPTION_DHCP4_NIS_SERVERS, options, &sbuf); - lease_parse_address_list(lease, l3cd, NM_DHCP_OPTION_DHCP4_NETBIOS_NAMESERVER, options, &sbuf); + lease_parse_address_list(lease, + l3cd, + iface, + NM_DHCP_OPTION_DHCP4_NETBIOS_NAMESERVER, + options, + &sbuf); lease_parse_private_options(lease, options); @@ -785,9 +890,7 @@ lease_save(NMDhcpNettools *self, NDhcp4ClientLease *lease, const char *lease_fil static void bound4_handle(NMDhcpNettools *self, guint event, NDhcp4ClientLease *lease) { - NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self); - NMDhcpClient *client = NM_DHCP_CLIENT(self); - const NMDhcpClientConfig *client_config; + NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self); nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL; gs_free_error GError *error = NULL; @@ -796,17 +899,14 @@ bound4_handle(NMDhcpNettools *self, guint event, NDhcp4ClientLease *lease) _LOGT("lease available (%s)", (event == N_DHCP4_CLIENT_EVENT_GRANTED) ? "granted" : "extended"); - client_config = nm_dhcp_client_get_config(client); - l3cd = lease_to_ip4_config(nm_dhcp_client_get_multi_idx(client), - client_config->iface, - nm_dhcp_client_get_ifindex(client), - lease, - &error); + l3cd = lease_to_ip4_config(self, lease, &error); if (!l3cd) { _LOGW("failure to parse lease: %s", error->message); - if (event == N_DHCP4_CLIENT_EVENT_GRANTED) + if (event == N_DHCP4_CLIENT_EVENT_GRANTED) { n_dhcp4_client_lease_decline(lease, "invalid lease"); + dhcp4_event_pop_all_events_on_idle(self); + } _nm_dhcp_client_notify(NM_DHCP_CLIENT(self), NM_DHCP_CLIENT_EVENT_TYPE_FAIL, NULL); return; @@ -854,7 +954,7 @@ dhcp4_event_handle(NMDhcpNettools *self, NDhcp4ClientEvent *event) case N_DHCP4_CLIENT_EVENT_OFFER: r = n_dhcp4_client_lease_get_server_identifier(event->offer.lease, &server_id); if (r) { - _LOGW("selecting lease failed: %d", r); + _LOGW("selecting lease failed: could not get DHCP server identifier (%d)", r); return; } @@ -870,11 +970,19 @@ dhcp4_event_handle(NMDhcpNettools *self, NDhcp4ClientEvent *event) return; } + if (!_nm_dhcp_client_accept_offer(NM_DHCP_CLIENT(self), &yiaddr.s_addr)) { + /* We don't log about this, the parent class is expected to notify about the reasons. */ + return; + } + _LOGT("selecting offered lease from %s for %s", _nm_utils_inet4_ntop(server_id.s_addr, addr_str), _nm_utils_inet4_ntop(yiaddr.s_addr, addr_str2)); r = n_dhcp4_client_lease_select(event->offer.lease); + + dhcp4_event_pop_all_events_on_idle(self); + if (r) { _LOGW("selecting lease failed: %d", r); return; @@ -906,22 +1014,79 @@ dhcp4_event_handle(NMDhcpNettools *self, NDhcp4ClientEvent *event) } } +static void +dhcp4_event_pop_all_events(NMDhcpNettools *self) +{ + NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self); + NDhcp4ClientEvent *event; + + while (!n_dhcp4_client_pop_event(priv->client, &event) && event) + dhcp4_event_handle(self, event); + + nm_clear_g_source_inst(&priv->pop_all_events_on_idle_source); +} + +static gboolean +dhcp4_event_pop_all_events_on_idle_cb(gpointer user_data) +{ + NMDhcpNettools *self = user_data; + NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self); + + nm_clear_g_source_inst(&priv->pop_all_events_on_idle_source); + dhcp4_event_pop_all_events(self); + return G_SOURCE_CONTINUE; +} + +static void +dhcp4_event_pop_all_events_on_idle(NMDhcpNettools *self) +{ + NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self); + + /* For the most part, NDhcp4Client gets driven from internal, that is + * by having events ready on the socket or the timerfd. For those + * events, we will poll on the (epoll) FD, then let it be processed + * by n_dhcp4_client_dispatch(), and pop the queued events. + * + * But certain commands (n_dhcp4_client_lease_select(), n_dhcp4_client_lease_accept(), + * n_dhcp4_client_lease_decline()) are initiated by the user. And they tend + * to log events. Logging is done by queuing a message, but that won't be processed, + * unless we pop the event. + * + * To ensure that those logging events get popped, schedule an idle handler to do that. + * + * Yes, this means, that the messages only get logged later, when the idle handler + * runs. The alternative seems even more problematic, because we don't know + * the current call-state, and it seems dangerous to pop unexpected events. + * E.g. we call n_dhcp4_client_lease_select() from inside the event-handler, + * it seems wrong to call dhcp4_event_pop_all_events() in that context again. + * + * See-also: https://github.com/nettools/n-dhcp4/issues/34 + */ + + if (!priv->pop_all_events_on_idle_source) { + priv->pop_all_events_on_idle_source = + nm_g_idle_add_source(dhcp4_event_pop_all_events_on_idle_cb, self); + } +} + static gboolean dhcp4_event_cb(int fd, GIOCondition condition, gpointer user_data) { NMDhcpNettools *self = user_data; NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self); - NDhcp4ClientEvent *event; int r; r = n_dhcp4_client_dispatch(priv->client); if (r < 0) { - /* FIXME: if any operation (e.g. send()) fails during the + /* If any operation (e.g. send()) fails during the * dispatch, n-dhcp4 returns an error without arming timers * or progressing state, so the only reasonable thing to do * is to move to failed state so that the client will be - * restarted. Ideally n-dhcp4 should retry failed operations - * a predefined number of times (possibly infinite). + * restarted. + * + * That means, n_dhcp4_client_dispatch() must not fail if it can + * somehow workaround the problem. A failure is really fatal + * and the client needs to be restarted. */ _LOGE("error %d dispatching events", r); nm_clear_g_source_inst(&priv->event_source); @@ -929,8 +1094,7 @@ dhcp4_event_cb(int fd, GIOCondition condition, gpointer user_data) return G_SOURCE_REMOVE; } - while (!n_dhcp4_client_pop_event(priv->client, &event) && event) - dhcp4_event_handle(self, event); + dhcp4_event_pop_all_events(self); return G_SOURCE_CONTINUE; } @@ -1056,6 +1220,8 @@ _accept(NMDhcpClient *client, const NML3ConfigData *l3cd, GError **error) if (!r) lease_save(self, priv->granted.lease, priv->lease_file); + dhcp4_event_pop_all_events_on_idle(self); + nm_clear_pointer(&priv->granted.lease, n_dhcp4_client_lease_unref); nm_clear_l3cd(&priv->granted.lease_l3cd); @@ -1091,6 +1257,8 @@ decline(NMDhcpClient *client, const NML3ConfigData *l3cd, const char *error_mess r = n_dhcp4_client_lease_decline(lease, error_message); + dhcp4_event_pop_all_events_on_idle(self); + if (r) { set_error_nettools(error, r, "failed to decline lease"); return FALSE; @@ -1155,18 +1323,20 @@ ip4_start(NMDhcpClient *client, GError **error) if (client_config->v4.last_address) inet_pton(AF_INET, client_config->v4.last_address, &last_addr); else { - /* - * TODO: we stick to the systemd-networkd lease file format. Quite easy for now to - * just use the functions in systemd code. Anyway, as in the end we just use the - * ip address from all the options found in the lease, write a function that parses - * the lease file just for the assigned address and returns it in &last_address. - * Then drop reference to systemd-networkd structures and functions. - */ - nm_auto(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL; - - dhcp_lease_load(&lease, lease_file); - if (lease) - sd_dhcp_lease_get_address(lease, &last_addr); + gs_free char *contents = NULL; + gs_free char *s_addr = NULL; + + nm_utils_file_get_contents(-1, + lease_file, + 64 * 1024, + NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, + &contents, + NULL, + NULL, + NULL); + nm_parse_env_file(contents, "ADDRESS", &s_addr); + if (s_addr) + nm_utils_parse_inaddr_bin(AF_INET, s_addr, NULL, &last_addr); } if (last_addr.s_addr) { @@ -1304,6 +1474,7 @@ dispose(GObject *object) nm_clear_g_free(&priv->lease_file); nm_clear_g_source_inst(&priv->event_source); + nm_clear_g_source_inst(&priv->pop_all_events_on_idle_source); nm_clear_pointer(&priv->granted.lease, n_dhcp4_client_lease_unref); nm_clear_l3cd(&priv->granted.lease_l3cd); nm_clear_pointer(&priv->probe, n_dhcp4_client_probe_free); |