dhcpcd-discuss

Re: FW: Does old_fqdn take on the value of new_dhcp6_fqdn?

Roy Marples

Fri Aug 21 23:13:45 2015

Hi Paul

On 2015-08-21 19:09, Walrath, Paul wrote:
That's kind of a dilemma isn't it?  An IT administrator sets up a
DHCPv4 server that provides a device one host name and domain name
(e.g. webhost4.webdomain4.walrath.name) and a DHCPv6 server that
provides a different host name and domain name
(webhost6.webdomain6.walrath.name).  That setup is the real problem
isn't it?  Why would an IT administrator want to give a device two
different names depending upon whether the device gets it from DHCPv4
or DHCPv6?

It would seem reasonable that a device would assign itself the most
recently received name.  As you suggest, this would cause it to flip
back and forth as the DHCPv4 and DHCPv6 replies with different names
are received.  In practice, this may be a real problem.

Right, in practice this is a real problem.
While the source IP address on a client can change with fairly minimal interruption - worst case is that daemons running on the client rebind to the new IP which causes the connection to terminate and re-associate.
But this is long standing DHCP behavior and is expected.

But a changing hostname is not expected at all.
The defacto norm is a hostname is set on the client itself.
The rarer case is hostname set via DHCP.
Rarer still is hostname set via DHCPv6.
And the rarest of all is a hostname change.

A lot of programs - Xauth, keychain and kerberos and others rely on the hostname being accurately set. Changing it has a dramatic effect.

20-hostname filters this by mapping new_dhcp6_fqdn to new_fqdn and
old_dhcp6_fqdn to old_fqdn, so that the DHCPv6 reply is treated as if
it were a DHCPv4 reply.

Perhaps this mapping isn't the real issue.  Perhaps the issue is that
30-hostname doesn't act on the event that a previously provided name
is no longer being provided.

Exactly so.
To be fair, most of the rules I took for renaming the host come from dhclient. And for good reason - dhcpcd can be a drop in replacement for a lot of dhclient based scripts.

Here's an example where the fqdn is removed from the DHCPv4 server
and, later, a new fqdn is entered.

Step 3.3 is what causes the problem.  The host name is not updated to
reflect that the DHCPv4 server has stopped providing the fqdn.  Step
5.3 does not update the host name to the new name provided because
$old_fqdn is "".  Step 6.3 does not update the host name to the new
name provided because $old_fqdn is different from the current value of
hostname.   If the host name as set to "" in 3.3, then it would be
updated in 5.2 because "" is one of the special initial values that
need_host() recognizes.

It seems to me that in step 3.3, the host name should be set to "".
Are there any issues with doing this?  It seems like it would solve
the problem.  The current hostname matches $old_fqdn, so it should be
ok to do the update.  I guess we need to think about what this change
would do in the following sequence:

From a technical perspective we cannot set the hostname to "" - some hostname(1) programs spit out the current hostname in this case.
So at best we could set localhost.


1) DHCPv4: host4.domain4.com
2) DHCPv4: host4.domain4.com
3) DHCPv6: <nothing>
4) DHCPv6: <nothing>
5) DHCPv4: host4.domain4.com
6) DHCPv4: host4.doman4.com

1.1) host4.domain4.com is received in a DHCPv4 reply via Option 81 Client FQDN.
1.2)  30-hostname is executed
	hostname is "localhost"
	new_fqdn is "host4.domain4.com"
	old_fqdn is ""
	new_host_name is ""
	new_domain_name is "domain4.com" (Set by 20-resolv.conf)
	old_domain_name is ""
1.2)  30-hostname sets the device's host name to "host4.domain4.com"

2.1) host4.domain4.com is received in a DHCPv4 reply via Option 81 Client FQDN.
2.2)  30-hostname is executed
	hostname is "host4.domain4.com"
	new_fqdn is "host4.domain4.com"
	old_fqdn is "host4.domain4.com"
	new_host_name is ""
	new_domain_name is "domain4.com" (Set by 20-resolv.conf)
	old_domain_name is "domain4.com"
2.3)  30-hostname sets the device's host name to "host4.domain4.com"

I should fix the hook so the hostname isn't changed if the same.

3.1)  The DHCPv6 server doesn't provide fqdn
3.2)  30-hostname is executed
	hostname is "host4.domain4.com"
	new_fqdn is ""
	old_fqdn is ""
	new_host_name is ""
	new_domain_name is ""
	old_domain_name is "domain4.com"
3.3)  30-hostname does nothing since $old_fqdn is zero length (it's
old_dhcp6_fqdn)

4.1)  The DHCPv6 server doesn't provide fqdn.
4.2)  30-hostname is executed
	hostname is "host4.domain4.com"
	new_fqdn is ""
	old_fqdn is ""
	new_host_name is ""
	new_domain_name is ""
	old_domain_name is ""
4.3)  30-hostname does nothing since $old_fqdn is zero length (it's
old_dhcp6_fqdn)

5.1) host4.domain4.com is received in a DHCPv4 reply via Option 81 Client FQDN.
5.2)  30-hostname is executed
	hostname is "host4.domain4.com"
	new_fqdn is "host4.domain4.com"
	old_fqdn is "host4.domain4.com"
	new_host_name is ""
	new_domain_name is "domain4.com" (Set by 20-resolv.conf)
	old_domain_name is ""
5.3)  30-hostname sets the device's host name to "host4.domain4.com"

6.1) host4.domain4.com is received in a DHCPv4 reply via Option 81 Client FQDN.
6.2)  30-hostname is executed
	hostname is "host4.domain4.com"
	new_fqdn is "host4.domain4.com"
	old_fqdn is "host4.domain4.com"
	new_host_name is ""
	new_domain_name is "domain4.com" (Set by 20-resolv.conf)
	old_domain_name is "domain4.com"
6.3)  30-hostname does nothing since $old_fqdn is not equal to hostname

I disagree with the 6.x section.
Based on your inputs it should go like this:
6.1) host4.doman4.com is received in a DHCPv4 reply via Option 81 Client FQDN.
 6.2)  30-hostname is executed
 	hostname is "host4.domain4.com"
 	new_fqdn is "host4.doman4.com"
 	old_fqdn is "host4.domain4.com"
 	new_host_name is ""
 	new_domain_name is "domain4.com" (Set by 20-resolv.conf)
 	old_domain_name is "domain4.com"
 6.3)  30-hostname sets the devices host name to "host4.doman4.com"


The above scenario assumes that doing the following in 30-hostname
does not change the value of old_fqdn when the script runs the next
time for a DHCPv4 reply.  Is this correct?  old_fqdn is only changed
locally for the current execution of this script?  When the next
DHCPv4 reply is received, old_fqdn will have the value of the fqdn
received in a previous DHCPv4 reply.  That affects what is shown in
5.2 for old_fqdn where a DHCPv4 reply is received after receiving two
DHCPv6 replies which do not have fqdn values.

case "$reason" in
BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
	new_fqdn="$new_dhcp6_fqdn"
	old_fqdn="$old_dhcp6_fqdn"
	;;
Esac

This is complicated stuff and I don't have a lot of shell script
experience to I may have made some mistakes, so I would recommend
caution in looking at my suggestion.  If you feel inclined to wade
into this, I won't be offended if you find some gross errors in my
analysis :-).

It's really quite easy.
If you dump a lease using dhcpcd you see this

hostname="foo.bar.com"

Now, when an action script is run, the variables are prefixed with new_ and the prior lease is prefixed with old_.
So regardless of any action the script makes we can assume this:

1) DHCPv4: host4.domain4.com
new_hostname="host4.domain4.com"
old_hostname=

2) DHCPv4: host4.domain4.com
new_hostname="host4.domain4.com"
old_hostname="host4.domain4.com"

3) DHCPv6: <nothing>
4) DHCPv6: <nothing>
5) DHCPv4: host4.domain4.com
new_hostname="host4.domain4.com"
old_hostname="host4.domain4.com"

6) DHCPv4: host4.doman4.com
new_hostname="host4.doman4.com"
old_hostname="host4.domain4.com"

In each invokation, you could create 99-abuse-vars hook script and set
new_hostname="dwayne"
old_hostname="dibbly"

And it would not affect the above because old_ and new_ vars are generated from the old and new leases each time the script is run. This has nothing to do with shell scripting - it's dhcpcd setting the environment before any scripts are run.

Now, if your head is starting to hurt at bit, reach for some paracetamol :)

1) DHCPv4: host4.domain4.com
2) DHCPv4: host4.domain4.com
3) DHCPv4: host4.domain4.com
4) DHCPv4: a.different.interface.com

Boom!
I have this laptop with wired and wireless, not hostname set two interfaces with no guarantee they will be on the same network.
dhcpcd of course controls them both.

Now, I for sure have no idea what to do here.
At best I can define the outcome as "undefined".

This is another reason why the hostname script acts like it does.
I suppose the only argument is that if old_hostname matches and new_hostname is blank we could set localhost and let the ball roll. If you file a ticket with a *condensed* summary of this large thread I'll make the change. There shouldn't be a new release for a while (I hope dhcpcd-6.9.2 fixed everyones problems!) so I'm happy to let it stew in trunk and let any testers see if it causes any issues.

Roy

Follow-Ups:
RE: FW: Does old_fqdn take on the value of new_dhcp6_fqdn?Walrath, Paul
References:
Does old_fqdn take on the value of new_dhcp6_fqdn?Walrath, Paul
RE: Does old_fqdn take on the value of new_dhcp6_fqdn?Roy Marples
Re: Does old_fqdn take on the value of new_dhcp6_fqdn?Roy Marples
Re: Does old_fqdn take on the value of new_dhcp6_fqdn?Roy Marples
RE: Does old_fqdn take on the value of new_dhcp6_fqdn?Walrath, Paul
RE: Does old_fqdn take on the value of new_dhcp6_fqdn?Roy Marples
RE: Does old_fqdn take on the value of new_dhcp6_fqdn?Walrath, Paul
Re: Does old_fqdn take on the value of new_dhcp6_fqdn?Roy Marples
FW: Does old_fqdn take on the value of new_dhcp6_fqdn?Walrath, Paul
Archive administrator: postmaster@marples.name