From d286aa9dfa9626234e7f40705c5313407177c431 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Wed, 26 Apr 2017 11:49:30 +0200 Subject: [PATCH 1/2] dhcp: simplify how hostname and FQDN are passed down to backends Since they are mutually exclusive, pass a string and a boolean to indicate whether we want to use the hostname or the FQDN option. --- src/devices/nm-device.c | 13 ++++----- src/dhcp/nm-dhcp-client.c | 16 +++++------ src/dhcp/nm-dhcp-client.h | 4 +-- src/dhcp/nm-dhcp-dhclient-utils.c | 40 ++++++++++++++------------- src/dhcp/nm-dhcp-dhclient-utils.h | 2 +- src/dhcp/nm-dhcp-dhclient.c | 17 ++++++------ src/dhcp/nm-dhcp-dhcpcd.c | 31 ++++++++++----------- src/dhcp/nm-dhcp-manager.c | 18 ++++++++----- src/dhcp/nm-dhcp-systemd.c | 41 ++++++++++++++-------------- src/dhcp/tests/test-dhcp-dhclient.c | 42 ++++++++++++++--------------- 10 files changed, 113 insertions(+), 111 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 3b1af608c9..f30c472c7b 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -12195,7 +12195,7 @@ nm_device_spawn_iface_helper (NMDevice *self) g_ptr_array_add (argv, g_strdup ("--dhcp4-required")); if (priv->dhcp4.client) { - const char *hostname, *fqdn; + const char *hostname; GBytes *client_id; client_id = nm_dhcp_client_get_client_id (priv->dhcp4.client); @@ -12209,15 +12209,12 @@ nm_device_spawn_iface_helper (NMDevice *self) hostname = nm_dhcp_client_get_hostname (priv->dhcp4.client); if (hostname) { - g_ptr_array_add (argv, g_strdup ("--dhcp4-hostname")); + if (nm_dhcp_client_get_use_fqdn (priv->dhcp4.client)) + g_ptr_array_add (argv, g_strdup ("--dhcp4-fqdn")); + else + g_ptr_array_add (argv, g_strdup ("--dhcp4-hostname")); g_ptr_array_add (argv, g_strdup (hostname)); } - - fqdn = nm_dhcp_client_get_fqdn (priv->dhcp4.client); - if (fqdn) { - g_ptr_array_add (argv, g_strdup ("--dhcp4-fqdn")); - g_ptr_array_add (argv, g_strdup (fqdn)); - } } configured = TRUE; diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c index 17986aa825..0906f5beba 100644 --- a/src/dhcp/nm-dhcp-client.c +++ b/src/dhcp/nm-dhcp-client.c @@ -68,7 +68,7 @@ typedef struct _NMDhcpClientPrivate { GByteArray * duid; GBytes * client_id; char * hostname; - char * fqdn; + gboolean use_fqdn; NMDhcpState state; pid_t pid; @@ -186,12 +186,12 @@ nm_dhcp_client_get_hostname (NMDhcpClient *self) return NM_DHCP_CLIENT_GET_PRIVATE (self)->hostname; } -const char * -nm_dhcp_client_get_fqdn (NMDhcpClient *self) +gboolean +nm_dhcp_client_get_use_fqdn (NMDhcpClient *self) { - g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); + g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); - return NM_DHCP_CLIENT_GET_PRIVATE (self)->fqdn; + return NM_DHCP_CLIENT_GET_PRIVATE (self)->use_fqdn; } /*****************************************************************************/ @@ -416,7 +416,7 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self, const char *dhcp_client_id, const char *dhcp_anycast_addr, const char *hostname, - const char *fqdn, + gboolean use_fqdn, const char *last_ip4_address) { NMDhcpClientPrivate *priv; @@ -437,8 +437,7 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self, g_clear_pointer (&priv->hostname, g_free); priv->hostname = g_strdup (hostname); - g_free (priv->fqdn); - priv->fqdn = g_strdup (fqdn); + priv->use_fqdn = use_fqdn; return NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, dhcp_anycast_addr, last_ip4_address); } @@ -911,7 +910,6 @@ dispose (GObject *object) g_clear_pointer (&priv->iface, g_free); g_clear_pointer (&priv->hostname, g_free); - g_clear_pointer (&priv->fqdn, g_free); g_clear_pointer (&priv->uuid, g_free); g_clear_pointer (&priv->client_id, g_bytes_unref); diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h index d790e3e10a..e41a59a265 100644 --- a/src/dhcp/nm-dhcp-client.h +++ b/src/dhcp/nm-dhcp-client.h @@ -123,13 +123,13 @@ GBytes *nm_dhcp_client_get_client_id (NMDhcpClient *self); const char *nm_dhcp_client_get_hostname (NMDhcpClient *self); -const char *nm_dhcp_client_get_fqdn (NMDhcpClient *self); +gboolean nm_dhcp_client_get_use_fqdn (NMDhcpClient *self); gboolean nm_dhcp_client_start_ip4 (NMDhcpClient *self, const char *dhcp_client_id, const char *dhcp_anycast_addr, const char *hostname, - const char *fqdn, + gboolean use_fqdn, const char *last_ip4_address); gboolean nm_dhcp_client_start_ip6 (NMDhcpClient *self, diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c index 5e1d056ee0..d267267981 100644 --- a/src/dhcp/nm-dhcp-dhclient-utils.c +++ b/src/dhcp/nm-dhcp-dhclient-utils.c @@ -93,29 +93,31 @@ grab_request_options (GPtrArray *store, const char* line) static void -add_hostname4 (GString *str, const char *hostname, const char *fqdn) +add_hostname4 (GString *str, const char *hostname, gboolean use_fqdn) { char *plain_hostname, *dot; - if (fqdn) { - g_string_append_printf (str, FQDN_FORMAT "\n", fqdn); - g_string_append (str, - "send fqdn.encoded on;\n" - "send fqdn.server-update on;\n"); - } else if (hostname) { - plain_hostname = g_strdup (hostname); - dot = strchr (plain_hostname, '.'); - /* get rid of the domain */ - if (dot) - *dot = '\0'; + if (hostname) { + if (use_fqdn) { + g_string_append_printf (str, FQDN_FORMAT "\n", hostname); + g_string_append (str, + "send fqdn.encoded on;\n" + "send fqdn.server-update on;\n"); + } else { + plain_hostname = g_strdup (hostname); + dot = strchr (plain_hostname, '.'); + /* get rid of the domain */ + if (dot) + *dot = '\0'; - g_string_append_printf (str, HOSTNAME4_FORMAT "\n", plain_hostname); - g_free (plain_hostname); + g_string_append_printf (str, HOSTNAME4_FORMAT "\n", plain_hostname); + g_free (plain_hostname); + } } } static void -add_ip4_config (GString *str, GBytes *client_id, const char *hostname, const char *fqdn) +add_ip4_config (GString *str, GBytes *client_id, const char *hostname, gboolean use_fqdn) { if (client_id) { const char *p; @@ -150,7 +152,7 @@ add_ip4_config (GString *str, GBytes *client_id, const char *hostname, const cha g_string_append (str, "; # added by NetworkManager\n"); } - add_hostname4 (str, hostname, fqdn); + add_hostname4 (str, hostname, use_fqdn); g_string_append_c (str, '\n'); @@ -267,7 +269,7 @@ nm_dhcp_dhclient_create_config (const char *interface, GBytes *client_id, const char *anycast_addr, const char *hostname, - const char *fqdn, + gboolean use_fqdn, const char *orig_path, const char *orig_contents, GBytes **out_new_client_id) @@ -324,7 +326,7 @@ nm_dhcp_dhclient_create_config (const char *interface, } /* Override config file hostname and use one from the connection */ - if (hostname || fqdn) { + if (hostname) { if (strncmp (p, HOSTNAME4_TAG, strlen (HOSTNAME4_TAG)) == 0) continue; if (strncmp (p, FQDN_TAG, strlen (FQDN_TAG)) == 0) @@ -384,7 +386,7 @@ nm_dhcp_dhclient_create_config (const char *interface, add_request (reqs, "dhcp6.domain-search"); add_request (reqs, "dhcp6.client-id"); } else { - add_ip4_config (new_contents, client_id, hostname, fqdn); + add_ip4_config (new_contents, client_id, hostname, use_fqdn); add_request (reqs, "rfc3442-classless-static-routes"); add_request (reqs, "ms-classless-static-routes"); add_request (reqs, "static-routes"); diff --git a/src/dhcp/nm-dhcp-dhclient-utils.h b/src/dhcp/nm-dhcp-dhclient-utils.h index d1ab1ba968..994b1b9f02 100644 --- a/src/dhcp/nm-dhcp-dhclient-utils.h +++ b/src/dhcp/nm-dhcp-dhclient-utils.h @@ -27,7 +27,7 @@ char *nm_dhcp_dhclient_create_config (const char *interface, GBytes *client_id, const char *anycast_addr, const char *hostname, - const char *fqdn, + gboolean use_fqdn, const char *orig_path, const char *orig_contents, GBytes **out_new_client_id); diff --git a/src/dhcp/nm-dhcp-dhclient.c b/src/dhcp/nm-dhcp-dhclient.c index f8339f9b7b..8a3f642a72 100644 --- a/src/dhcp/nm-dhcp-dhclient.c +++ b/src/dhcp/nm-dhcp-dhclient.c @@ -182,7 +182,7 @@ merge_dhclient_config (NMDhcpDhclient *self, GBytes *client_id, const char *anycast_addr, const char *hostname, - const char *fqdn, + gboolean use_fqdn, const char *orig_path, GBytes **out_new_client_id, GError **error) @@ -203,7 +203,7 @@ merge_dhclient_config (NMDhcpDhclient *self, } } - new = nm_dhcp_dhclient_create_config (iface, is_ip6, client_id, anycast_addr, hostname, fqdn, orig_path, orig, out_new_client_id); + new = nm_dhcp_dhclient_create_config (iface, is_ip6, client_id, anycast_addr, hostname, use_fqdn, orig_path, orig, out_new_client_id); g_assert (new); success = g_file_set_contents (conf_file, new, -1, error); g_free (new); @@ -291,7 +291,7 @@ create_dhclient_config (NMDhcpDhclient *self, GBytes *client_id, const char *dhcp_anycast_addr, const char *hostname, - const char *fqdn, + gboolean use_fqdn, GBytes **out_new_client_id) { char *orig = NULL, *new = NULL; @@ -311,7 +311,7 @@ create_dhclient_config (NMDhcpDhclient *self, error = NULL; success = merge_dhclient_config (self, iface, new, is_ip6, client_id, dhcp_anycast_addr, - hostname, fqdn, orig, out_new_client_id, &error); + hostname, use_fqdn, orig, out_new_client_id, &error); if (!success) { _LOGW ("error creating dhclient configuration: %s", error->message); g_error_free (error); @@ -502,17 +502,18 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self); GBytes *client_id; gs_unref_bytes GBytes *new_client_id = NULL; - const char *iface, *uuid, *hostname, *fqdn; + const char *iface, *uuid, *hostname; gboolean success = FALSE; + gboolean use_fqdn; iface = nm_dhcp_client_get_iface (client); uuid = nm_dhcp_client_get_uuid (client); client_id = nm_dhcp_client_get_client_id (client); hostname = nm_dhcp_client_get_hostname (client); - fqdn = nm_dhcp_client_get_fqdn (client); + use_fqdn = nm_dhcp_client_get_use_fqdn (client); priv->conf_file = create_dhclient_config (self, iface, FALSE, uuid, client_id, dhcp_anycast_addr, - hostname, fqdn, &new_client_id); + hostname, use_fqdn, &new_client_id); if (priv->conf_file) { if (new_client_id) nm_dhcp_client_set_client_id (client, new_client_id); @@ -540,7 +541,7 @@ ip6_start (NMDhcpClient *client, uuid = nm_dhcp_client_get_uuid (client); hostname = nm_dhcp_client_get_hostname (client); - priv->conf_file = create_dhclient_config (self, iface, TRUE, uuid, NULL, dhcp_anycast_addr, hostname, NULL, NULL); + priv->conf_file = create_dhclient_config (self, iface, TRUE, uuid, NULL, dhcp_anycast_addr, hostname, TRUE, NULL); if (!priv->conf_file) { _LOGW ("error creating dhclient configuration file"); return FALSE; diff --git a/src/dhcp/nm-dhcp-dhcpcd.c b/src/dhcp/nm-dhcp-dhcpcd.c index c8643881fc..54af2d4302 100644 --- a/src/dhcp/nm-dhcp-dhcpcd.c +++ b/src/dhcp/nm-dhcp-dhcpcd.c @@ -89,7 +89,7 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last pid_t pid = -1; GError *error = NULL; char *pid_contents = NULL, *binary_name, *cmd_str, *dot; - const char *iface, *dhcpcd_path, *hostname, *fqdn; + const char *iface, *dhcpcd_path, *hostname; gs_free char *prefix = NULL; g_return_val_if_fail (priv->pid_file == NULL, FALSE); @@ -138,22 +138,23 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last #endif hostname = nm_dhcp_client_get_hostname (client); - fqdn = nm_dhcp_client_get_fqdn (client); - if (fqdn) { - g_ptr_array_add (argv, (gpointer) "-h"); - g_ptr_array_add (argv, (gpointer) fqdn); - g_ptr_array_add (argv, (gpointer) "-F"); - g_ptr_array_add (argv, (gpointer) "both"); - } else if (hostname) { - prefix = strdup (hostname); - dot = strchr (prefix, '.'); - /* get rid of the domain */ - if (dot) - *dot = '\0'; + if (hostname) { + if (nm_dhcp_client_get_use_fqdn (client)) { + g_ptr_array_add (argv, (gpointer) "-h"); + g_ptr_array_add (argv, (gpointer) hostname); + g_ptr_array_add (argv, (gpointer) "-F"); + g_ptr_array_add (argv, (gpointer) "both"); + } else { + prefix = strdup (hostname); + dot = strchr (prefix, '.'); + /* get rid of the domain */ + if (dot) + *dot = '\0'; - g_ptr_array_add (argv, (gpointer) "-h"); /* Send hostname to DHCP server */ - g_ptr_array_add (argv, (gpointer) prefix); + g_ptr_array_add (argv, (gpointer) "-h"); /* Send hostname to DHCP server */ + g_ptr_array_add (argv, (gpointer) prefix); + } } g_ptr_array_add (argv, (gpointer) iface); diff --git a/src/dhcp/nm-dhcp-manager.c b/src/dhcp/nm-dhcp-manager.c index 9c1fbb38bf..c3018ef5c5 100644 --- a/src/dhcp/nm-dhcp-manager.c +++ b/src/dhcp/nm-dhcp-manager.c @@ -163,7 +163,7 @@ client_start (NMDhcpManager *self, guint32 timeout, const char *dhcp_anycast_addr, const char *hostname, - const char *fqdn, + gboolean hostname_use_fqdn, gboolean info_only, NMSettingIP6ConfigPrivacy privacy, const char *last_ip4_address, @@ -209,7 +209,7 @@ client_start (NMDhcpManager *self, if (ipv6) success = nm_dhcp_client_start_ip6 (client, dhcp_anycast_addr, ipv6_ll_addr, hostname, info_only, privacy, needed_prefixes); else - success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname, fqdn, last_ip4_address); + success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname, hostname_use_fqdn, last_ip4_address); if (!success) { remove_client (self, client); @@ -245,17 +245,21 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self, const char *last_ip_address) { const char *hostname = NULL; - const char *fqdn = NULL; + gboolean use_fqdn = FALSE; g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); if (send_hostname) { - hostname = get_send_hostname (self, dhcp_hostname); - fqdn = dhcp_fqdn; + if (dhcp_fqdn) { + hostname = dhcp_fqdn; + use_fqdn = TRUE; + } else + hostname = get_send_hostname (self, dhcp_hostname); } + return client_start (self, iface, ifindex, hwaddr, uuid, priority, FALSE, NULL, dhcp_client_id, timeout, dhcp_anycast_addr, hostname, - fqdn, FALSE, 0, last_ip_address, 0); + use_fqdn, FALSE, 0, last_ip_address, 0); } /* Caller owns a reference to the NMDhcpClient on return */ @@ -282,7 +286,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self, if (send_hostname) hostname = get_send_hostname (self, dhcp_hostname); return client_start (self, iface, ifindex, hwaddr, uuid, priority, TRUE, - ll_addr, NULL, timeout, dhcp_anycast_addr, hostname, NULL, info_only, + ll_addr, NULL, timeout, dhcp_anycast_addr, hostname, TRUE, info_only, privacy, NULL, needed_prefixes); } diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c index 7067275bc3..96be65ae1c 100644 --- a/src/dhcp/nm-dhcp-systemd.c +++ b/src/dhcp/nm-dhcp-systemd.c @@ -580,7 +580,7 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last const uint8_t *client_id = NULL; size_t client_id_len = 0; struct in_addr last_addr = { 0 }; - const char *hostname, *fqdn; + const char *hostname; int r, i; gboolean success = FALSE; guint16 arp_type; @@ -687,29 +687,28 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last hostname = nm_dhcp_client_get_hostname (client); if (hostname) { - char *prefix, *dot; + if (nm_dhcp_client_get_use_fqdn (client)) { + r = sd_dhcp_client_set_hostname (priv->client4, hostname); + if (r < 0) { + _LOGW ("failed to set DHCP FQDN (%d)", r); + goto error; + } + } else { + char *prefix, *dot; - prefix = strdup (hostname); - dot = strchr (prefix, '.'); - /* get rid of the domain */ - if (dot) - *dot = '\0'; + prefix = strdup (hostname); + dot = strchr (prefix, '.'); + /* get rid of the domain */ + if (dot) + *dot = '\0'; - r = sd_dhcp_client_set_hostname (priv->client4, prefix); - free (prefix); + r = sd_dhcp_client_set_hostname (priv->client4, prefix); + free (prefix); - if (r < 0) { - _LOGW ("failed to set DHCP hostname (%d)", r); - goto error; - } - } - - fqdn = nm_dhcp_client_get_fqdn (client); - if (fqdn) { - r = sd_dhcp_client_set_hostname (priv->client4, fqdn); - if (r < 0) { - _LOGW ("failed to set DHCP FQDN (%d)", r); - goto error; + if (r < 0) { + _LOGW ("failed to set DHCP hostname (%d)", r); + goto error; + } } } diff --git a/src/dhcp/tests/test-dhcp-dhclient.c b/src/dhcp/tests/test-dhcp-dhclient.c index 3ba5f10b20..6e75578d69 100644 --- a/src/dhcp/tests/test-dhcp-dhclient.c +++ b/src/dhcp/tests/test-dhcp-dhclient.c @@ -40,7 +40,7 @@ test_config (const char *orig, const char *expected, gboolean ipv6, const char *hostname, - const char *fqdn, + gboolean use_fqdn, const char *dhcp_client_id, GBytes *expected_new_client_id, const char *iface, @@ -60,7 +60,7 @@ test_config (const char *orig, client_id, anycast_addr, hostname, - fqdn, + use_fqdn, "/path/to/dhclient.conf", orig, &new_client_id); @@ -105,7 +105,7 @@ static const char *orig_missing_expected = \ static void test_orig_missing (void) { - test_config (NULL, orig_missing_expected, FALSE, NULL, NULL, NULL, NULL, "eth0", NULL); + test_config (NULL, orig_missing_expected, FALSE, NULL, FALSE, NULL, NULL, "eth0", NULL); } /*****************************************************************************/ @@ -134,7 +134,7 @@ static void test_override_client_id (void) { test_config (override_client_id_orig, override_client_id_expected, - FALSE, NULL, NULL, + FALSE, NULL, FALSE, "11:22:33:44:55:66", NULL, "eth0", @@ -163,7 +163,7 @@ static void test_quote_client_id (void) { test_config (NULL, quote_client_id_expected, - FALSE, NULL, NULL, + FALSE, NULL, FALSE, "1234", NULL, "eth0", @@ -192,7 +192,7 @@ static void test_ascii_client_id (void) { test_config (NULL, ascii_client_id_expected, - FALSE, NULL, NULL, + FALSE, NULL, FALSE, "qb:cd:ef:12:34:56", NULL, "eth0", @@ -221,7 +221,7 @@ static void test_hex_single_client_id (void) { test_config (NULL, hex_single_client_id_expected, - FALSE, NULL, NULL, + FALSE, NULL, FALSE, "ab:cd:e:12:34:56", NULL, "eth0", @@ -258,7 +258,7 @@ test_existing_hex_client_id (void) new_client_id = g_bytes_new (bytes, sizeof (bytes)); test_config (existing_hex_client_id_orig, existing_hex_client_id_expected, - FALSE, NULL, NULL, + FALSE, NULL, FALSE, NULL, new_client_id, "eth0", @@ -298,7 +298,7 @@ test_existing_ascii_client_id (void) memcpy (buf + 1, EACID, NM_STRLEN (EACID)); new_client_id = g_bytes_new (buf, sizeof (buf)); test_config (existing_ascii_client_id_orig, existing_ascii_client_id_expected, - FALSE, NULL, NULL, + FALSE, NULL, FALSE, NULL, new_client_id, "eth0", @@ -327,8 +327,8 @@ static void test_fqdn (void) { test_config (NULL, fqdn_expected, - FALSE, NULL, - "foo.bar.com", NULL, + FALSE, "foo.bar.com", + TRUE, NULL, NULL, "eth0", NULL); @@ -367,8 +367,8 @@ test_fqdn_options_override (void) { test_config (fqdn_options_override_orig, fqdn_options_override_expected, - FALSE, NULL, - "example2.com", NULL, + FALSE, "example2.com", + TRUE, NULL, NULL, "eth0", NULL); @@ -400,7 +400,7 @@ static void test_override_hostname (void) { test_config (override_hostname_orig, override_hostname_expected, - FALSE, "blahblah", NULL, + FALSE, "blahblah", FALSE, NULL, NULL, "eth0", @@ -428,7 +428,7 @@ static void test_override_hostname6 (void) { test_config (override_hostname6_orig, override_hostname6_expected, - TRUE, "blahblah.local", NULL, + TRUE, "blahblah.local", TRUE, NULL, NULL, "eth0", @@ -454,7 +454,7 @@ test_nonfqdn_hostname6 (void) /* Non-FQDN hostname can now be used with dhclient */ test_config (NULL, nonfqdn_hostname6_expected, TRUE, "blahblah", - NULL, NULL, + TRUE, NULL, NULL, "eth0", NULL); @@ -489,7 +489,7 @@ test_existing_alsoreq (void) { test_config (existing_alsoreq_orig, existing_alsoreq_expected, FALSE, NULL, - NULL, + FALSE, NULL, NULL, "eth0", @@ -528,7 +528,7 @@ test_existing_req (void) { test_config (existing_req_orig, existing_req_expected, FALSE, NULL, - NULL, + FALSE, NULL, NULL, "eth0", @@ -567,7 +567,7 @@ static void test_existing_multiline_alsoreq (void) { test_config (existing_multiline_alsoreq_orig, existing_multiline_alsoreq_expected, - FALSE, NULL, NULL, + FALSE, NULL, FALSE, NULL, NULL, "eth0", @@ -781,7 +781,7 @@ static void test_interface1 (void) { test_config (interface1_orig, interface1_expected, - FALSE, NULL, NULL, + FALSE, NULL, FALSE, NULL, NULL, "eth0", @@ -826,7 +826,7 @@ static void test_interface2 (void) { test_config (interface2_orig, interface2_expected, - FALSE, NULL, NULL, + FALSE, NULL, FALSE, NULL, NULL, "eth1", From cf5fab8f55b1f54e28da8b78bc02c65d29134787 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 28 Apr 2017 11:40:51 +0200 Subject: [PATCH 2/2] dhcp: allow FQDNs in ipv4.dhcp-hostname If users wrote a FQDN in ipv4.dhcp-hostname presumably it's because they really want to send the full value, not only the host part, so let's send it as-is. This obviously is a change in behavior, but only for users that have a FQDN in ipv4.dhcp-hostname, where it's not clear if they really want the domain to be stripped. When the property is unset, we keep sending only the host part of the system hostname to maintain backwards compatibility. This commit aligns NM behavior to initscripts. --- src/dhcp/nm-dhcp-dhclient-utils.c | 14 ++--------- src/dhcp/nm-dhcp-dhcpcd.c | 13 +++------- src/dhcp/nm-dhcp-manager.c | 40 +++++++++++++++++++++---------- src/dhcp/nm-dhcp-systemd.c | 30 +++++++---------------- 4 files changed, 40 insertions(+), 57 deletions(-) diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c index d267267981..11f868e260 100644 --- a/src/dhcp/nm-dhcp-dhclient-utils.c +++ b/src/dhcp/nm-dhcp-dhclient-utils.c @@ -95,24 +95,14 @@ grab_request_options (GPtrArray *store, const char* line) static void add_hostname4 (GString *str, const char *hostname, gboolean use_fqdn) { - char *plain_hostname, *dot; - if (hostname) { if (use_fqdn) { g_string_append_printf (str, FQDN_FORMAT "\n", hostname); g_string_append (str, "send fqdn.encoded on;\n" "send fqdn.server-update on;\n"); - } else { - plain_hostname = g_strdup (hostname); - dot = strchr (plain_hostname, '.'); - /* get rid of the domain */ - if (dot) - *dot = '\0'; - - g_string_append_printf (str, HOSTNAME4_FORMAT "\n", plain_hostname); - g_free (plain_hostname); - } + } else + g_string_append_printf (str, HOSTNAME4_FORMAT "\n", hostname); } } diff --git a/src/dhcp/nm-dhcp-dhcpcd.c b/src/dhcp/nm-dhcp-dhcpcd.c index 54af2d4302..66a31acf10 100644 --- a/src/dhcp/nm-dhcp-dhcpcd.c +++ b/src/dhcp/nm-dhcp-dhcpcd.c @@ -88,9 +88,8 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last GPtrArray *argv = NULL; pid_t pid = -1; GError *error = NULL; - char *pid_contents = NULL, *binary_name, *cmd_str, *dot; + char *pid_contents = NULL, *binary_name, *cmd_str; const char *iface, *dhcpcd_path, *hostname; - gs_free char *prefix = NULL; g_return_val_if_fail (priv->pid_file == NULL, FALSE); @@ -146,14 +145,8 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last g_ptr_array_add (argv, (gpointer) "-F"); g_ptr_array_add (argv, (gpointer) "both"); } else { - prefix = strdup (hostname); - dot = strchr (prefix, '.'); - /* get rid of the domain */ - if (dot) - *dot = '\0'; - - g_ptr_array_add (argv, (gpointer) "-h"); /* Send hostname to DHCP server */ - g_ptr_array_add (argv, (gpointer) prefix); + g_ptr_array_add (argv, (gpointer) "-h"); + g_ptr_array_add (argv, (gpointer) hostname); } } diff --git a/src/dhcp/nm-dhcp-manager.c b/src/dhcp/nm-dhcp-manager.c index c3018ef5c5..fff9f9ec30 100644 --- a/src/dhcp/nm-dhcp-manager.c +++ b/src/dhcp/nm-dhcp-manager.c @@ -219,15 +219,6 @@ client_start (NMDhcpManager *self, return client; } -static const char * -get_send_hostname (NMDhcpManager *self, const char *setting_hostname) -{ - NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - - /* Always prefer the explicit dhcp-send-hostname if given */ - return setting_hostname ? setting_hostname : priv->default_hostname; -} - /* Caller owns a reference to the NMDhcpClient on return */ NMDhcpClient * nm_dhcp_manager_start_ip4 (NMDhcpManager *self, @@ -244,17 +235,36 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self, const char *dhcp_anycast_addr, const char *last_ip_address) { + NMDhcpManagerPrivate *priv; const char *hostname = NULL; + gs_free char *hostname_tmp = NULL; gboolean use_fqdn = FALSE; + char *dot; g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); + priv = NM_DHCP_MANAGER_GET_PRIVATE (self); if (send_hostname) { + /* Use, in order of preference: + * 1. FQDN from configuration + * 2. hostname from configuration + * 3. system hostname (only host part) + */ if (dhcp_fqdn) { hostname = dhcp_fqdn; use_fqdn = TRUE; - } else - hostname = get_send_hostname (self, dhcp_hostname); + } else if (dhcp_hostname) + hostname = dhcp_hostname; + else { + hostname = priv->default_hostname; + if (hostname) { + hostname_tmp = g_strdup (hostname); + dot = strchr (hostname_tmp, '.'); + if (dot) + *dot = '\0'; + hostname = hostname_tmp; + } + } } return client_start (self, iface, ifindex, hwaddr, uuid, priority, FALSE, NULL, @@ -279,12 +289,16 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self, NMSettingIP6ConfigPrivacy privacy, guint needed_prefixes) { + NMDhcpManagerPrivate *priv; const char *hostname = NULL; g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); + priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - if (send_hostname) - hostname = get_send_hostname (self, dhcp_hostname); + if (send_hostname) { + /* Always prefer the explicit dhcp-hostname if given */ + hostname = dhcp_hostname ? dhcp_hostname : priv->default_hostname; + } return client_start (self, iface, ifindex, hwaddr, uuid, priority, TRUE, ll_addr, NULL, timeout, dhcp_anycast_addr, hostname, TRUE, info_only, privacy, NULL, needed_prefixes); diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c index 96be65ae1c..aa90270101 100644 --- a/src/dhcp/nm-dhcp-systemd.c +++ b/src/dhcp/nm-dhcp-systemd.c @@ -687,28 +687,14 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last hostname = nm_dhcp_client_get_hostname (client); if (hostname) { - if (nm_dhcp_client_get_use_fqdn (client)) { - r = sd_dhcp_client_set_hostname (priv->client4, hostname); - if (r < 0) { - _LOGW ("failed to set DHCP FQDN (%d)", r); - goto error; - } - } else { - char *prefix, *dot; - - prefix = strdup (hostname); - dot = strchr (prefix, '.'); - /* get rid of the domain */ - if (dot) - *dot = '\0'; - - r = sd_dhcp_client_set_hostname (priv->client4, prefix); - free (prefix); - - if (r < 0) { - _LOGW ("failed to set DHCP hostname (%d)", r); - goto error; - } + /* FIXME: sd-dhcp decides which hostname/FQDN option to send (12 or 81) + * only based on whether the hostname has a domain part or not. At the + * moment there is no way to force one or another. + */ + r = sd_dhcp_client_set_hostname (priv->client4, hostname); + if (r < 0) { + _LOGW ("failed to set DHCP hostname to '%s' (%d)", hostname, r); + goto error; } }