dhclient: use fqdn.fqdn for server DDNS updates
dhclient only supports fqdn.fqdn for server DDNS updates with DHCPv6. And even though the underlying DHCP options that fqdn.fqdn controls allow non-qualified hostnames on the wire, dhclient does not. So we must require a fully-qualified name for DHCPv6. Second, while no-client-updates seems like it should be "off", doing that apparently makes dhclient set the "O" flag to 1 which appears to be a bug, and results in the server not doing the DDNS update. So we must stop setting that option too. Found by: Alexander Groß
This commit is contained in:
@@ -39,8 +39,8 @@
|
|||||||
#define HOSTNAME4_TAG "send host-name"
|
#define HOSTNAME4_TAG "send host-name"
|
||||||
#define HOSTNAME4_FORMAT HOSTNAME4_TAG " \"%s\"; # added by NetworkManager"
|
#define HOSTNAME4_FORMAT HOSTNAME4_TAG " \"%s\"; # added by NetworkManager"
|
||||||
|
|
||||||
#define HOSTNAME6_TAG "send fqdn.fqdn"
|
#define FQDN_TAG "send fqdn.fqdn"
|
||||||
#define HOSTNAME6_FORMAT HOSTNAME6_TAG " \"%s\"; # added by NetworkManager"
|
#define FQDN_FORMAT FQDN_TAG " \"%s\"; # added by NetworkManager"
|
||||||
|
|
||||||
#define ALSOREQ_TAG "also request "
|
#define ALSOREQ_TAG "also request "
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ add_also_request (GPtrArray *array, const char *item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_hostname (GString *str, const char *format, const char *hostname)
|
add_hostname4 (GString *str, const char *format, const char *hostname)
|
||||||
{
|
{
|
||||||
char *plain_hostname, *dot;
|
char *plain_hostname, *dot;
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ add_ip4_config (GString *str, GBytes *client_id, const char *hostname)
|
|||||||
g_string_append (str, "; # added by NetworkManager\n");
|
g_string_append (str, "; # added by NetworkManager\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
add_hostname (str, HOSTNAME4_FORMAT "\n", hostname);
|
add_hostname4 (str, HOSTNAME4_FORMAT "\n", hostname);
|
||||||
|
|
||||||
g_string_append_c (str, '\n');
|
g_string_append_c (str, '\n');
|
||||||
|
|
||||||
@@ -125,13 +125,18 @@ add_ip4_config (GString *str, GBytes *client_id, const char *hostname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_ip6_config (GString *str, const char *hostname)
|
add_hostname6 (GString *str, const char *hostname)
|
||||||
{
|
{
|
||||||
add_hostname (str, HOSTNAME6_FORMAT "\n", hostname);
|
/* dhclient only supports the fqdn.fqdn for DHCPv6 and requires a fully-
|
||||||
|
* qualified name for this option, so we must require one here too.
|
||||||
|
*/
|
||||||
|
if (hostname && strchr (hostname, '.')) {
|
||||||
|
g_string_append_printf (str, FQDN_FORMAT "\n", hostname);
|
||||||
g_string_append (str,
|
g_string_append (str,
|
||||||
"send fqdn.encoded on;\n"
|
"send fqdn.encoded on;\n"
|
||||||
"send fqdn.no-client-update on;\n"
|
|
||||||
"send fqdn.server-update on;\n");
|
"send fqdn.server-update on;\n");
|
||||||
|
g_string_append_c (str, '\n');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GBytes *
|
static GBytes *
|
||||||
@@ -232,7 +237,7 @@ nm_dhcp_dhclient_create_config (const char *interface,
|
|||||||
if (hostname) {
|
if (hostname) {
|
||||||
if (strncmp (p, HOSTNAME4_TAG, strlen (HOSTNAME4_TAG)) == 0)
|
if (strncmp (p, HOSTNAME4_TAG, strlen (HOSTNAME4_TAG)) == 0)
|
||||||
continue;
|
continue;
|
||||||
if (strncmp (p, HOSTNAME6_TAG, strlen (HOSTNAME6_TAG)) == 0)
|
if (strncmp (p, FQDN_TAG, strlen (FQDN_TAG)) == 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,7 +295,7 @@ nm_dhcp_dhclient_create_config (const char *interface,
|
|||||||
g_string_append_c (new_contents, '\n');
|
g_string_append_c (new_contents, '\n');
|
||||||
|
|
||||||
if (is_ip6) {
|
if (is_ip6) {
|
||||||
add_ip6_config (new_contents, hostname);
|
add_hostname6 (new_contents, hostname);
|
||||||
add_also_request (alsoreq, "dhcp6.name-servers");
|
add_also_request (alsoreq, "dhcp6.name-servers");
|
||||||
add_also_request (alsoreq, "dhcp6.domain-search");
|
add_also_request (alsoreq, "dhcp6.domain-search");
|
||||||
add_also_request (alsoreq, "dhcp6.client-id");
|
add_also_request (alsoreq, "dhcp6.client-id");
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
static void
|
static void
|
||||||
test_config (const char *orig,
|
test_config (const char *orig,
|
||||||
const char *expected,
|
const char *expected,
|
||||||
|
gboolean ipv6,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
const char *dhcp_client_id,
|
const char *dhcp_client_id,
|
||||||
GBytes *expected_new_client_id,
|
GBytes *expected_new_client_id,
|
||||||
@@ -55,7 +56,7 @@ test_config (const char *orig,
|
|||||||
}
|
}
|
||||||
|
|
||||||
new = nm_dhcp_dhclient_create_config (iface,
|
new = nm_dhcp_dhclient_create_config (iface,
|
||||||
FALSE,
|
ipv6,
|
||||||
client_id,
|
client_id,
|
||||||
anycast_addr,
|
anycast_addr,
|
||||||
hostname,
|
hostname,
|
||||||
@@ -103,7 +104,7 @@ static const char *orig_missing_expected = \
|
|||||||
static void
|
static void
|
||||||
test_orig_missing (void)
|
test_orig_missing (void)
|
||||||
{
|
{
|
||||||
test_config (NULL, orig_missing_expected, NULL, NULL, NULL, "eth0", NULL);
|
test_config (NULL, orig_missing_expected, FALSE, NULL, NULL, NULL, "eth0", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************/
|
/*******************************************/
|
||||||
@@ -132,7 +133,7 @@ static void
|
|||||||
test_override_client_id (void)
|
test_override_client_id (void)
|
||||||
{
|
{
|
||||||
test_config (override_client_id_orig, override_client_id_expected,
|
test_config (override_client_id_orig, override_client_id_expected,
|
||||||
NULL,
|
FALSE, NULL,
|
||||||
"11:22:33:44:55:66",
|
"11:22:33:44:55:66",
|
||||||
NULL,
|
NULL,
|
||||||
"eth0",
|
"eth0",
|
||||||
@@ -161,7 +162,7 @@ static void
|
|||||||
test_quote_client_id (void)
|
test_quote_client_id (void)
|
||||||
{
|
{
|
||||||
test_config (NULL, quote_client_id_expected,
|
test_config (NULL, quote_client_id_expected,
|
||||||
NULL,
|
FALSE, NULL,
|
||||||
"1234",
|
"1234",
|
||||||
NULL,
|
NULL,
|
||||||
"eth0",
|
"eth0",
|
||||||
@@ -190,7 +191,7 @@ static void
|
|||||||
test_ascii_client_id (void)
|
test_ascii_client_id (void)
|
||||||
{
|
{
|
||||||
test_config (NULL, ascii_client_id_expected,
|
test_config (NULL, ascii_client_id_expected,
|
||||||
NULL,
|
FALSE, NULL,
|
||||||
"qb:cd:ef:12:34:56",
|
"qb:cd:ef:12:34:56",
|
||||||
NULL,
|
NULL,
|
||||||
"eth0",
|
"eth0",
|
||||||
@@ -219,7 +220,7 @@ static void
|
|||||||
test_hex_single_client_id (void)
|
test_hex_single_client_id (void)
|
||||||
{
|
{
|
||||||
test_config (NULL, hex_single_client_id_expected,
|
test_config (NULL, hex_single_client_id_expected,
|
||||||
NULL,
|
FALSE, NULL,
|
||||||
"ab:cd:e:12:34:56",
|
"ab:cd:e:12:34:56",
|
||||||
NULL,
|
NULL,
|
||||||
"eth0",
|
"eth0",
|
||||||
@@ -256,7 +257,7 @@ test_existing_hex_client_id (void)
|
|||||||
|
|
||||||
new_client_id = g_bytes_new (bytes, sizeof (bytes));
|
new_client_id = g_bytes_new (bytes, sizeof (bytes));
|
||||||
test_config (existing_hex_client_id_orig, existing_hex_client_id_expected,
|
test_config (existing_hex_client_id_orig, existing_hex_client_id_expected,
|
||||||
NULL,
|
FALSE, NULL,
|
||||||
NULL,
|
NULL,
|
||||||
new_client_id,
|
new_client_id,
|
||||||
"eth0",
|
"eth0",
|
||||||
@@ -296,7 +297,7 @@ test_existing_ascii_client_id (void)
|
|||||||
memcpy (buf + 1, EACID, STRLEN (EACID));
|
memcpy (buf + 1, EACID, STRLEN (EACID));
|
||||||
new_client_id = g_bytes_new (buf, sizeof (buf));
|
new_client_id = g_bytes_new (buf, sizeof (buf));
|
||||||
test_config (existing_ascii_client_id_orig, existing_ascii_client_id_expected,
|
test_config (existing_ascii_client_id_orig, existing_ascii_client_id_expected,
|
||||||
NULL,
|
FALSE, NULL,
|
||||||
NULL,
|
NULL,
|
||||||
new_client_id,
|
new_client_id,
|
||||||
"eth0",
|
"eth0",
|
||||||
@@ -329,7 +330,58 @@ static void
|
|||||||
test_override_hostname (void)
|
test_override_hostname (void)
|
||||||
{
|
{
|
||||||
test_config (override_hostname_orig, override_hostname_expected,
|
test_config (override_hostname_orig, override_hostname_expected,
|
||||||
"blahblah",
|
FALSE, "blahblah",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
"eth0",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************/
|
||||||
|
|
||||||
|
static const char *override_hostname6_orig = \
|
||||||
|
"send fqdn.fqdn \"foobar\";\n";
|
||||||
|
|
||||||
|
static const char *override_hostname6_expected = \
|
||||||
|
"# Created by NetworkManager\n"
|
||||||
|
"# Merged from /path/to/dhclient.conf\n"
|
||||||
|
"\n"
|
||||||
|
"send fqdn.fqdn \"blahblah.local\"; # added by NetworkManager\n"
|
||||||
|
"send fqdn.encoded on;\n"
|
||||||
|
"send fqdn.server-update on;\n"
|
||||||
|
"\n"
|
||||||
|
"also request dhcp6.name-servers;\n"
|
||||||
|
"also request dhcp6.domain-search;\n"
|
||||||
|
"also request dhcp6.client-id;\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_override_hostname6 (void)
|
||||||
|
{
|
||||||
|
test_config (override_hostname6_orig, override_hostname6_expected,
|
||||||
|
TRUE, "blahblah.local",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
"eth0",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************/
|
||||||
|
|
||||||
|
static const char *nonfqdn_hostname6_expected = \
|
||||||
|
"# Created by NetworkManager\n"
|
||||||
|
"\n"
|
||||||
|
"also request dhcp6.name-servers;\n"
|
||||||
|
"also request dhcp6.domain-search;\n"
|
||||||
|
"also request dhcp6.client-id;\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_nonfqdn_hostname6 (void)
|
||||||
|
{
|
||||||
|
/* Non-FQDN hostname can't be used with dhclient */
|
||||||
|
test_config (NULL, nonfqdn_hostname6_expected,
|
||||||
|
TRUE, "blahblah",
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
"eth0",
|
"eth0",
|
||||||
@@ -364,7 +416,7 @@ static void
|
|||||||
test_existing_alsoreq (void)
|
test_existing_alsoreq (void)
|
||||||
{
|
{
|
||||||
test_config (existing_alsoreq_orig, existing_alsoreq_expected,
|
test_config (existing_alsoreq_orig, existing_alsoreq_expected,
|
||||||
NULL,
|
FALSE, NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
"eth0",
|
"eth0",
|
||||||
@@ -403,7 +455,7 @@ static void
|
|||||||
test_existing_multiline_alsoreq (void)
|
test_existing_multiline_alsoreq (void)
|
||||||
{
|
{
|
||||||
test_config (existing_multiline_alsoreq_orig, existing_multiline_alsoreq_expected,
|
test_config (existing_multiline_alsoreq_orig, existing_multiline_alsoreq_expected,
|
||||||
NULL,
|
FALSE, NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
"eth0",
|
"eth0",
|
||||||
@@ -721,6 +773,8 @@ main (int argc, char **argv)
|
|||||||
g_test_add_func ("/dhcp/dhclient/existing-hex-client-id", test_existing_hex_client_id);
|
g_test_add_func ("/dhcp/dhclient/existing-hex-client-id", test_existing_hex_client_id);
|
||||||
g_test_add_func ("/dhcp/dhclient/existing-ascii-client-id", test_existing_ascii_client_id);
|
g_test_add_func ("/dhcp/dhclient/existing-ascii-client-id", test_existing_ascii_client_id);
|
||||||
g_test_add_func ("/dhcp/dhclient/override_hostname", test_override_hostname);
|
g_test_add_func ("/dhcp/dhclient/override_hostname", test_override_hostname);
|
||||||
|
g_test_add_func ("/dhcp/dhclient/override_hostname6", test_override_hostname6);
|
||||||
|
g_test_add_func ("/dhcp/dhclient/nonfqdn_hostname6", test_nonfqdn_hostname6);
|
||||||
g_test_add_func ("/dhcp/dhclient/existing_alsoreq", test_existing_alsoreq);
|
g_test_add_func ("/dhcp/dhclient/existing_alsoreq", test_existing_alsoreq);
|
||||||
g_test_add_func ("/dhcp/dhclient/existing_multiline_alsoreq", test_existing_multiline_alsoreq);
|
g_test_add_func ("/dhcp/dhclient/existing_multiline_alsoreq", test_existing_multiline_alsoreq);
|
||||||
g_test_add_func ("/dhcp/dhclient/duids", test_duids);
|
g_test_add_func ("/dhcp/dhclient/duids", test_duids);
|
||||||
|
Reference in New Issue
Block a user