summary refs log tree commit diff
path: root/src/dhcp
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2019-12-26 06:49:35 +0100
committerMichael Biebl <biebl@debian.org>2019-12-26 06:49:35 +0100
commit724bcc5c7be3aed3646ed2b2989c34d438217176 (patch)
treee46ca78149b3517bc5ebc9fd31d6d9d11a6561b6 /src/dhcp
parent28028b26b3371756811e95d894f709f4b1207c00 (diff)
New upstream version 1.22.2 upstream/1.22.2
Diffstat (limited to 'src/dhcp')
-rw-r--r--src/dhcp/nm-dhcp-nettools.c78
-rw-r--r--src/dhcp/nm-dhcp-utils.h2
-rw-r--r--src/dhcp/tests/test-dhcp-utils.c55
3 files changed, 111 insertions, 24 deletions
diff --git a/src/dhcp/nm-dhcp-nettools.c b/src/dhcp/nm-dhcp-nettools.c
index e557c004..1f76c64c 100644
--- a/src/dhcp/nm-dhcp-nettools.c
+++ b/src/dhcp/nm-dhcp-nettools.c
@@ -128,6 +128,7 @@ lease_option_next_route (struct in_addr *destp,
 	uint8_t *data = *datap;
 	size_t n_data = *n_datap;
 	uint8_t plen;
+	uint8_t bytes;
 
 	if (classless) {
 		if (!lease_option_consume (&plen, sizeof (plen), &data, &n_data))
@@ -136,7 +137,9 @@ lease_option_next_route (struct in_addr *destp,
 		if (plen > 32)
 			return FALSE;
 
-		if (!lease_option_consume (&dest, plen / 8, &data, &n_data))
+		bytes = plen == 0 ? 0 : ((plen - 1) / 8) + 1;
+
+		if (!lease_option_consume (&dest, bytes, &data, &n_data))
 			return FALSE;
 	} else {
 		if (!lease_option_next_in_addr (&dest, &data, &n_data))
@@ -246,10 +249,10 @@ lease_option_print_domain_name (GString *str, uint8_t *cache, size_t *n_cachep,
 				return TRUE;
 			}
 
-			if (!first) {
+			if (!first)
 				g_string_append_c(str, '.');
+			else
 				first = FALSE;
-			}
 
 			if (!lease_option_print_label (str, n_label, domainp, n_domainp))
 				return FALSE;
@@ -775,34 +778,57 @@ lease_parse_domainname (NDhcp4ClientLease *lease,
 	                           str->str);
 }
 
+char **
+nm_dhcp_parse_search_list (guint8 *data, size_t n_data)
+{
+	GPtrArray *array = NULL;
+	guint8 *cache = data;
+	size_t n_cache = 0;
+
+	for (;;) {
+		nm_auto_free_gstring GString *domain = NULL;
+
+		nm_gstring_prepare (&domain);
+
+		if (!lease_option_print_domain_name (domain, cache, &n_cache, &data, &n_data))
+			break;
+
+		if (!array)
+			array = g_ptr_array_new ();
+
+		g_ptr_array_add (array, g_string_free (domain, FALSE));
+		domain = NULL;
+	}
+
+	if (array) {
+		g_ptr_array_add (array, NULL);
+		return (char **) g_ptr_array_free (array, FALSE);
+	} else
+		return NULL;
+}
+
 static void
 lease_parse_search_domains (NDhcp4ClientLease *lease,
                             NMIP4Config *ip4_config,
                             GHashTable *options)
 {
 	nm_auto_free_gstring GString *str = NULL;
-	uint8_t *data, *cache;
-	size_t n_data, n_cache = 0;
+	uint8_t *data;
+	size_t n_data;
+	gs_strfreev char **domains = NULL;
+	guint i;
 	int r;
 
 	r = n_dhcp4_client_lease_query (lease, NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST, &data, &n_data);
 	if (r)
 		return;
 
-	cache = data;
-
+	domains = nm_dhcp_parse_search_list (data, n_data);
 	nm_gstring_prepare (&str);
 
-	for (;;) {
-		nm_auto_free_gstring GString *domain = NULL;
-
-		nm_gstring_prepare (&domain);
-
-		if (!lease_option_print_domain_name (domain, cache, &n_cache, &data, &n_data))
-			break;
-
-		g_string_append (nm_gstring_add_space_delimiter (str), domain->str);
-		nm_ip4_config_add_search (ip4_config, domain->str);
+	for (i = 0; domains && domains[i]; i++) {
+		g_string_append (nm_gstring_add_space_delimiter (str), domains[i]);
+		nm_ip4_config_add_search (ip4_config, domains[i]);
 	}
 	nm_dhcp_option_add_option (options,
 	                           _nm_dhcp_option_dhcp4_options,
@@ -924,11 +950,12 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
 /*****************************************************************************/
 
 static void
-lease_save (NDhcp4ClientLease *lease, const char *lease_file)
+lease_save (NMDhcpNettools *self, NDhcp4ClientLease *lease, const char *lease_file)
 {
 	struct in_addr a_address;
 	nm_auto_free_gstring GString *new_contents = NULL;
 	char sbuf[NM_UTILS_INET_ADDRSTRLEN];
+	gs_free_error GError *error = NULL;
 
 	nm_assert (lease);
 	nm_assert (lease_file);
@@ -942,10 +969,11 @@ lease_save (NDhcp4ClientLease *lease, const char *lease_file)
 	g_string_append_printf (new_contents,
 	                        "ADDRESS=%s\n", nm_utils_inet4_ntop (a_address.s_addr, sbuf));
 
-	g_file_set_contents (lease_file,
-	                     new_contents->str,
-	                     -1,
-	                     NULL);
+	if (!g_file_set_contents (lease_file,
+	                          new_contents->str,
+	                          -1,
+	                          &error))
+		_LOGW ("error saving lease to %s: %s", lease_file, error->message);
 }
 
 static void
@@ -975,7 +1003,7 @@ bound4_handle (NMDhcpNettools *self, NDhcp4ClientLease *lease)
 	}
 
 	nm_dhcp_option_add_requests_to_options (options, _nm_dhcp_option_dhcp4_options);
-	lease_save (lease, priv->lease_file);
+	lease_save (self, lease, priv->lease_file);
 
 	nm_dhcp_client_set_state (NM_DHCP_CLIENT (self),
 	                          NM_DHCP_STATE_BOUND,
@@ -1283,8 +1311,10 @@ ip4_start (NMDhcpClient *client,
 			sd_dhcp_lease_get_address (lease, &last_addr);
 	}
 
-	if (last_addr.s_addr)
+	if (last_addr.s_addr) {
 		n_dhcp4_client_probe_config_set_requested_ip (config, last_addr);
+		n_dhcp4_client_probe_config_set_init_reboot (config, TRUE);
+	}
 
 	/* Add requested options */
 	for (i = 0; _nm_dhcp_option_dhcp4_options[i].name; i++) {
diff --git a/src/dhcp/nm-dhcp-utils.h b/src/dhcp/nm-dhcp-utils.h
index e4c33314..ecb91809 100644
--- a/src/dhcp/nm-dhcp-utils.h
+++ b/src/dhcp/nm-dhcp-utils.h
@@ -36,5 +36,7 @@ gboolean nm_dhcp_utils_get_leasefile_path (int addr_family,
                                            const char *uuid,
                                            char **out_leasefile_path);
 
+char **nm_dhcp_parse_search_list (guint8 *data, size_t n_data);
+
 #endif /* __NETWORKMANAGER_DHCP_UTILS_H__ */
 
diff --git a/src/dhcp/tests/test-dhcp-utils.c b/src/dhcp/tests/test-dhcp-utils.c
index d0389069..e601534e 100644
--- a/src/dhcp/tests/test-dhcp-utils.c
+++ b/src/dhcp/tests/test-dhcp-utils.c
@@ -200,6 +200,60 @@ test_vendor_option_metered (void)
 }
 
 static void
+test_parse_search_list (void)
+{
+	guint8 *data;
+	char **domains;
+
+	data = (guint8 []) {
+		0x05, 'l', 'o', 'c', 'a', 'l',
+		0x00
+	};
+	domains = nm_dhcp_parse_search_list (data, 7);
+	g_assert (domains);
+	g_assert_cmpint (g_strv_length (domains), ==, 1);
+	g_assert_cmpstr (domains[0], ==, "local");
+	g_strfreev (domains);
+
+	data = (guint8 []) {
+		0x04, 't', 'e', 's', 't',
+		0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+		0x03, 'c', 'o', 'm',
+		0x00,
+		0xc0, 0x05,
+		0x03, 'a', 'b', 'c',
+		0xc0, 0x0d,
+		0x06, 'f', 'o', 'o', 'b', 'a', 'r',
+		0x00
+	};
+	domains = nm_dhcp_parse_search_list (data, 34);
+	g_assert (domains);
+	g_assert_cmpint (g_strv_length (domains), ==, 4);
+	g_assert_cmpstr (domains[0], ==, "test.example.com");
+	g_assert_cmpstr (domains[1], ==, "example.com");
+	g_assert_cmpstr (domains[2], ==, "abc.com");
+	g_assert_cmpstr (domains[3], ==, "foobar");
+	g_strfreev (domains);
+
+	data = (guint8 []) {
+		0x40, 'b', 'a', 'd',
+	};
+	domains = nm_dhcp_parse_search_list (data, 4);
+	g_assert (!domains);
+
+	data = (guint8 []) {
+		0x04, 'o', 'k', 'a', 'y',
+		0x00,
+		0x40, 'b', 'a', 'd',
+	};
+	domains = nm_dhcp_parse_search_list (data, 10);
+	g_assert (domains);
+	g_assert_cmpint (g_strv_length (domains), ==, 1);
+	g_assert_cmpstr (domains[0], ==, "okay");
+	g_strfreev (domains);
+}
+
+static void
 ip4_test_route (NMIP4Config *ip4_config,
                 guint route_num,
                 const char *expected_dest,
@@ -732,6 +786,7 @@ int main (int argc, char **argv)
 	g_test_add_func ("/dhcp/ip4-prefix-classless", test_ip4_prefix_classless);
 	g_test_add_func ("/dhcp/client-id-from-string", test_client_id_from_string);
 	g_test_add_func ("/dhcp/vendor-option-metered", test_vendor_option_metered);
+	g_test_add_func ("/dhcp/parse-search-list", test_parse_search_list);
 
 	return g_test_run ();
 }