OpenBSD CVS

CVS log for src/sbin/dhcpleased/engine.c


[BACK] Up to [local] / src / sbin / dhcpleased

Request diff between arbitrary revisions


Default branch: MAIN


Revision 1.45 / (download) - annotate - [select for diffs], Mon Jun 3 17:58:33 2024 UTC (7 days, 22 hours ago) by deraadt
Branch: MAIN
CVS Tags: HEAD
Changes since 1.44: +2 -2 lines
Diff to previous 1.44 (colored)

more sleepy florian knf issues

Revision 1.44 / (download) - annotate - [select for diffs], Sun Jun 2 12:39:26 2024 UTC (9 days, 4 hours ago) by florian
Branch: MAIN
Changes since 1.43: +2 -2 lines
Diff to previous 1.43 (colored)

Switch to rebinding at the rebinding time not when one timeout past.

Spotted while hacking on dhcp6leased(8)

Revision 1.43 / (download) - annotate - [select for diffs], Tue Feb 13 12:53:05 2024 UTC (3 months, 3 weeks ago) by florian
Branch: MAIN
CVS Tags: OPENBSD_7_5_BASE, OPENBSD_7_5
Changes since 1.42: +6 -4 lines
Diff to previous 1.42 (colored)

Only generate a new xid at the start of getting a new lease.

"RFC 2131 4.1 Constructing and sending DHCP messages" has this:

| Selecting a new 'xid' for each retransmission is an implementation
| decision.  A client may choose to reuse the same 'xid' or select a new
| 'xid' for each retransmitted message.

We used to change xid for each request / response cycle but this ran
into problems with slow dhcp servers where we would change the xid too
frequently and would ignore late coming replies from the server.

Andre S points out that table 5 in "4.4.1 Initialization and
allocation of network address" says for the xid field in "DHCPREQUEST"
messages:

| 'xid' from server DHCPOFFER message

This seems to suggest that we need to use the same xid for the whole
DHCPDISCOVER / DHCPOFFER / DHCPREQUEST / DHCPACK exchange of messages.

Nothing else in the RFC is saying this though.

But since there are DHCP servers out there that depend on this, we
only generate a new xid when entering the INIT, REBOOTING and RENEWING
state.

I do wonder if we should just go with a static value of 0x04, which
was chosen by a fair dice roll, so guaranteed to be random.

Issue reported, initial diff and fix tested by Andre S
deraadt likes this version
OK tb

Revision 1.42 / (download) - annotate - [select for diffs], Fri Jan 26 21:14:08 2024 UTC (4 months, 2 weeks ago) by jan
Branch: MAIN
Changes since 1.41: +17 -12 lines
Diff to previous 1.41 (colored)

Put checksum flags in bpf_hdr to use them in userland dhcpleased.

Thus, dhcpleased accept non-calculated checksums which were verified by
hardware/hypervisor.

With tweaks from dlg@

ok bluhm@
mkay tobhe@

Revision 1.41 / (download) - annotate - [select for diffs], Thu Dec 14 09:58:37 2023 UTC (5 months, 4 weeks ago) by claudio
Branch: MAIN
Changes since 1.40: +2 -2 lines
Diff to previous 1.40 (colored)

Use imsg_get_fd() to access the fd passed with the imsg.
Go ahead florian@ OK tb@

Revision 1.40 / (download) - annotate - [select for diffs], Sat Nov 25 12:00:39 2023 UTC (6 months, 2 weeks ago) by florian
Branch: MAIN
Changes since 1.39: +60 -1 lines
Diff to previous 1.39 (colored)

First stab at IPv6-only preferred from RFC8925.

This lets dhcpleased(8) request "IPv6-only preferred". If the
server replies with this option dhcpleased stops and does not request
a lease and deconfigures IPv4 on the interface.

For now this is pretty much useless unless one dynamically configures
pf(4) to act as a CLAT. gelatod(8) from ports can help with this.

However, this helps me while hacking on a kernel based stateless CLAT
by moving dhcpleased out of the way while having an IPv6-mostly
network configured to compare behaviour with macOS.

Input jmc
OK phessler
Input & OK sthen

Revision 1.39 / (download) - annotate - [select for diffs], Fri Nov 3 15:02:06 2023 UTC (7 months, 1 week ago) by tb
Branch: MAIN
Changes since 1.38: +2 -2 lines
Diff to previous 1.38 (colored)

typo: ignorning -> ignoring

From Laurie Tratt, ok florian

Revision 1.38 / (download) - annotate - [select for diffs], Thu May 5 14:44:59 2022 UTC (2 years, 1 month ago) by tb
Branch: MAIN
CVS Tags: OPENBSD_7_4_BASE, OPENBSD_7_4, OPENBSD_7_3_BASE, OPENBSD_7_3, OPENBSD_7_2_BASE, OPENBSD_7_2
Changes since 1.37: +2 -2 lines
Diff to previous 1.37 (colored)

Switch the log_warnx() about trailing garbage to log_debug(). After a
maintenance window, my ISP started sending an unexpected 'ff' byte at
the very end which created noise in the log.  Apparently this came up
before.

From and ok florian

Revision 1.37 / (download) - annotate - [select for diffs], Wed May 4 05:57:18 2022 UTC (2 years, 1 month ago) by florian
Branch: MAIN
Changes since 1.36: +19 -9 lines
Diff to previous 1.36 (colored)

As found by n18fuhtm AT tutanota.com there are dhcp servers that send a
domain name option with length 1 and a single \0.
We strip trailing \0 and then end up with length 0.
This is a protocol violation, the minimum length for domain name option
is 1, and we ignore the lease.

Since we are not going to get this fixed this server side, we might as
well just pretend that we didn't receive a domain name (or host name).
We only ever care about them in the installer anyway. Not getting a
lease because of this corner case is not helpful.

OK deraadt

Revision 1.36 / (download) - annotate - [select for diffs], Wed Feb 16 10:35:57 2022 UTC (2 years, 3 months ago) by florian
Branch: MAIN
CVS Tags: OPENBSD_7_1_BASE, OPENBSD_7_1
Changes since 1.35: +18 -6 lines
Diff to previous 1.35 (colored)

According to RFC 2132, 2. BOOTP Extension/DHCP Option Field Format
ASCII data should not include trailing NUL but we MUST delete trailing
NULs on receiving.

Jan Vlach ( janus AT volny.cz) reported that Microsoft DHCP server
sends the domain name option with a trailing NUL which the installer
put into /etc/myname as a trailing ^@ which smtpd does not like.

Fix some whitespace while here.

Input & OK millert

Revision 1.35 / (download) - annotate - [select for diffs], Tue Jan 4 06:20:37 2022 UTC (2 years, 5 months ago) by florian
Branch: MAIN
Changes since 1.34: +14 -1 lines
Diff to previous 1.34 (colored)

Make host name DHCP option configurable.
Diff from hagen@sdf.org, tweaks by me.
OK phessler
testing & OK bket

Revision 1.34 / (download) - annotate - [select for diffs], Sat Dec 18 10:34:19 2021 UTC (2 years, 5 months ago) by florian
Branch: MAIN
Changes since 1.33: +3 -4 lines
Diff to previous 1.33 (colored)

Make sure we receive what we expect over imsg.

Instead of repairing potential garbage ensure that we receive proper C
strings. Inspired by a similar diff by deraadt@ for ldapd.

Revision 1.33 / (download) - annotate - [select for diffs], Mon Dec 13 16:12:10 2021 UTC (2 years, 5 months ago) by florian
Branch: MAIN
Changes since 1.32: +5 -3 lines
Diff to previous 1.32 (colored)

Only generate a new xid on state change.

When we first request a lease (INIT or REBOOTING state) we run with
very short timeouts. If the dhcp server is slow to respond we already
have a new xid and ignore the server's response. This goes on until we
increase the timeout high enough. If we just stick to an xid this will
not happen and we accept "late" responses.

RFC 2131 has:
Selecting a new 'xid' for each retransmission is an implementation
decision.  A client may choose to reuse the same 'xid' or select a new
'xid' for each retransmitted message.

Problem seen by phessler on german train wifi.
OK phessler

Revision 1.32 / (download) - annotate - [select for diffs], Mon Dec 13 11:03:23 2021 UTC (2 years, 5 months ago) by florian
Branch: MAIN
Changes since 1.31: +3 -3 lines
Diff to previous 1.31 (colored)

Treat xid as a uint32_t in network byte order on the wire.

Internally this doesn't matter since we only care about equality.
This makes logging output comparable to tcpdump(8).

Pointed out by joel@
OK claudio

Revision 1.31 / (download) - annotate - [select for diffs], Mon Dec 13 11:02:26 2021 UTC (2 years, 5 months ago) by florian
Branch: MAIN
Changes since 1.30: +22 -22 lines
Diff to previous 1.30 (colored)

Replace struct member assignment with struct assignment to make the
code more compact. No binary change.
OK claudio

Revision 1.30 / (download) - annotate - [select for diffs], Thu Dec 9 16:20:12 2021 UTC (2 years, 6 months ago) by florian
Branch: MAIN
Changes since 1.29: +80 -24 lines
Diff to previous 1.29 (colored)

Rework in which state to add and not add the server-ip and
requested-ip option as well as setting ciaddr.

This started with joel@ pointing out that their CPE is ignoring
RENEWING and REBINDING requests when ciaddr was not set.

RFC 2131 4.3.6, Table 4 has a good overview, we got a bunch of it
wrong.

Previously the logic for this was all over the place which made it
difficult to reason about, it is now contained in the engine process
in request_dhcp_request() and request_dhcp_discover().

Problem pointed out by, lots of testing and review as well as OK joel@
Additional testing and 50% review benno@

Revision 1.29 / (download) - annotate - [select for diffs], Sun Nov 14 18:13:19 2021 UTC (2 years, 6 months ago) by florian
Branch: MAIN
Changes since 1.28: +2 -2 lines
Diff to previous 1.28 (colored)

When we transition from RENEWING to REBINDING state we have to
calculate the next timeout based on the rebinding time (T2), not
renewal time (T1). At this point T1 already expired and we would wait
way too long, past the lease lifetime.

Spotted while investigating a problem reported by Zack Newman on misc@

Revision 1.28 / (download) - annotate - [select for diffs], Thu Oct 28 09:44:49 2021 UTC (2 years, 7 months ago) by kn
Branch: MAIN
Changes since 1.27: +1 -8 lines
Diff to previous 1.27 (colored)

Accept server replies from any server port

There is no requirement other than replying to client port 68/udp
as per RFC 2131, so drop the 67/udp check.

Same conclusion from florian
Reported and tested by Roc Vallès < vallesroc AT gmail DOT com>, thanks!

Revision 1.27 / (download) - annotate - [select for diffs], Wed Sep 15 15:18:23 2021 UTC (2 years, 8 months ago) by florian
Branch: MAIN
CVS Tags: OPENBSD_7_0_BASE, OPENBSD_7_0
Changes since 1.26: +6 -11 lines
Diff to previous 1.26 (colored)

Rewrite and simplify dhcpleasectl(8).

With this

dhcpleasectl em0

does the same as

dhclient em0

used to do. To please people's muscle memory one can be aliased to the other.

earlier version OK benno

with lots of help massaging the output & OK deraadt

Revision 1.26 / (download) - annotate - [select for diffs], Wed Sep 15 06:08:01 2021 UTC (2 years, 8 months ago) by florian
Branch: MAIN
Changes since 1.25: +23 -1 lines
Diff to previous 1.25 (colored)

Remove configured routes no longer present in lease.
Problem reported by claudio
OK benno

Revision 1.25 / (download) - annotate - [select for diffs], Thu Aug 12 12:41:08 2021 UTC (2 years, 10 months ago) by florian
Branch: MAIN
Changes since 1.24: +82 -6 lines
Diff to previous 1.24 (colored)

Make it possible to ignore routes or nameservers from a lease as well
as ignoring servers entirely.
Tested by bket
Parser looks reasonable to benno
man page OK jmc

Revision 1.24 / (download) - annotate - [select for diffs], Wed Aug 4 05:56:58 2021 UTC (2 years, 10 months ago) by florian
Branch: MAIN
Changes since 1.23: +2 -2 lines
Diff to previous 1.23 (colored)

Do not enter a tight INIT -> REQUESTING -> INIT loop when the dhcp
server responds to our DHCPDISCOVER but is then slow to respond to our
DHCPREQUEST.
MAX_EXP_BACKOFF_FAST was introduced to get us quickly out of the
REBOOTING state when we switch networks and no dhcp server would NAK
our old lease but just ignore us. This is not the issue here, there is
a dhcp server willing to talk to us, it's just slow.
Problem reported, tested & OK jca

Revision 1.23 / (download) - annotate - [select for diffs], Sun Aug 1 09:07:03 2021 UTC (2 years, 10 months ago) by florian
Branch: MAIN
Changes since 1.22: +2 -2 lines
Diff to previous 1.22 (colored)

Do not abuse the IMSG_CTL_SEND_REQUEST imsg to transition to
REBOOTING. There will be a few more cases internal to dhcpleased that
have nothing to do with the control socket.
While here move requesting a new lease via a call to dhclient under
ifndef SMALL, nothing on the ramdisk uses this.

Revision 1.22 / (download) - annotate - [select for diffs], Mon Jul 26 09:26:36 2021 UTC (2 years, 10 months ago) by florian
Branch: MAIN
Changes since 1.21: +120 -19 lines
Diff to previous 1.21 (colored)

Implement possibility to send vendor class identifier (option 60) and
client identifier (option 61). Some dhcp servers expect these options
and refuse to hand out a lease without them.
Need for vendor class identifier pointed out & tested by bket
Need for client identifier pointed out by sthen
Input & reads OK sthen (as part of a larger diff)
OK kn (as part of a larger diff)

Revision 1.21 / (download) - annotate - [select for diffs], Sun Jul 25 12:35:58 2021 UTC (2 years, 10 months ago) by florian
Branch: MAIN
Changes since 1.20: +8 -1 lines
Diff to previous 1.20 (colored)

If the lease didn't contain renewal or rebinding options set the
defaults before validating the times to prevent excessive logging.
Found the hard way & OK brynet

Revision 1.20 / (download) - annotate - [select for diffs], Fri Jul 23 11:56:01 2021 UTC (2 years, 10 months ago) by florian
Branch: MAIN
Changes since 1.19: +4 -4 lines
Diff to previous 1.19 (colored)

When dhcpleasectl asks to send a new request on an interface we are
probably stuck in some way and the user wants a mostly clean slate.

If we already have an IP address transition to state REBOOTING so that
we no longer unicast dhcp requests. We will then try to reacquire our
lease twice before giving up and transition to INIT and send dhcp
discover messages accepting any IP address.

Revision 1.19 / (download) - annotate - [select for diffs], Sun Jul 18 12:33:41 2021 UTC (2 years, 10 months ago) by florian
Branch: MAIN
Changes since 1.18: +32 -14 lines
Diff to previous 1.18 (colored)

Ignore routers option when a classless static routes option is present
as mandated by RFC3442.
Pointed out by, initial diff, testing & OK bket@

Revision 1.18 / (download) - annotate - [select for diffs], Mon Jul 12 15:09:18 2021 UTC (2 years, 11 months ago) by beck
Branch: MAIN
Changes since 1.17: +3 -3 lines
Diff to previous 1.17 (colored)

Change the error reporting pattern throughout the tree when unveil
fails to report the path that the failure occured on. Suggested by
deraadt@ after some tech discussion.

Work done and verified by Ashton Fagg <ashton@fagg.id.au>

ok deraadt@ semarie@ claudio@

Revision 1.17 / (download) - annotate - [select for diffs], Sun Jun 20 08:31:45 2021 UTC (2 years, 11 months ago) by florian
Branch: MAIN
Changes since 1.16: +39 -8 lines
Diff to previous 1.16 (colored)

Put (boot) filename, next-server, host-name and domain-name into lease
file for the installer.

Revision 1.16 / (download) - annotate - [select for diffs], Fri Jun 18 11:44:48 2021 UTC (2 years, 11 months ago) by florian
Branch: MAIN
Changes since 1.15: +3 -1 lines
Diff to previous 1.15 (colored)

fix SMALL build

Revision 1.15 / (download) - annotate - [select for diffs], Wed Jun 16 14:06:17 2021 UTC (2 years, 11 months ago) by florian
Branch: MAIN
Changes since 1.14: +90 -19 lines
Diff to previous 1.14 (colored)

Implement classless static routes dhcp option.

For this we need to be able to handle multiple routes being sent from
the engine to the main process as well as to the control tool.
The configuration of the various cases (default route, directly
connected routes, non-default route via a gateway) was inspired by
dhclient's set_routes() and should behave the same way.

Tested by Uwe Werler

Revision 1.14 / (download) - annotate - [select for diffs], Sat May 1 11:51:59 2021 UTC (3 years, 1 month ago) by florian
Branch: MAIN
Changes since 1.13: +6 -3 lines
Diff to previous 1.13 (colored)

Allow running in single user mode where /var/empty doesn't exist by
switching from chroot("/var/empty") to unveil("/", "").
This is just an extra pair of suspenders since these processes
pledge(2) to not access the filesystem.
OK deraadt

Revision 1.13 / (download) - annotate - [select for diffs], Wed Apr 14 23:35:24 2021 UTC (3 years, 1 month ago) by deraadt
Branch: MAIN
CVS Tags: OPENBSD_6_9_BASE, OPENBSD_6_9
Changes since 1.12: +4 -4 lines
Diff to previous 1.12 (colored)

my fingers cannot avoid KNF'ing as I review code

Revision 1.12 / (download) - annotate - [select for diffs], Fri Apr 9 14:46:39 2021 UTC (3 years, 2 months ago) by martijn
Branch: MAIN
Changes since 1.11: +14 -13 lines
Diff to previous 1.11 (colored)

When a DHCP server sends an invalid T1 or T2 default back to the default
values as specified in RFC2131 section 4.4.5. Allows my Comtrend VI-3223u
to work.

OK florian@

Revision 1.11 / (download) - annotate - [select for diffs], Mon Mar 22 15:34:07 2021 UTC (3 years, 2 months ago) by otto
Branch: MAIN
Changes since 1.10: +2 -2 lines
Diff to previous 1.10 (colored)

Avoid overflow by writing x = (y * 7) / 8 as x = y - (y / 8); ok florian

Revision 1.10 / (download) - annotate - [select for diffs], Tue Mar 16 17:40:28 2021 UTC (3 years, 2 months ago) by florian
Branch: MAIN
Changes since 1.9: +4 -1 lines
Diff to previous 1.9 (colored)

Don't (try to) deconfigure an interface that was never configured.

Revision 1.9 / (download) - annotate - [select for diffs], Sun Mar 7 18:39:11 2021 UTC (3 years, 3 months ago) by florian
Branch: MAIN
Changes since 1.8: +153 -105 lines
Diff to previous 1.8 (colored)

Reduce debug logging by moving protocol level debug log
behind -vv or by deleting unneeded output.
While here reword some debug output to make it more useful.
(There is more to be done here.)

Revision 1.8 / (download) - annotate - [select for diffs], Sun Mar 7 16:22:01 2021 UTC (3 years, 3 months ago) by florian
Branch: MAIN
Changes since 1.7: +7 -9 lines
Diff to previous 1.7 (colored)

No need to cap the exponential backoff here, iface_timeout() already
handles this for us by doing a state transition if we have been stuck
in "rebooting" or "requesting" for too long.
Makes the code a bit simpler and we only have one place were we need
to special case the timeout cap.

Revision 1.7 / (download) - annotate - [select for diffs], Sat Mar 6 18:33:44 2021 UTC (3 years, 3 months ago) by florian
Branch: MAIN
Changes since 1.6: +24 -16 lines
Diff to previous 1.6 (colored)

Turns out there are dhcp servers that ignore DHCPREQUEST messages when
they don't like them instead of sending a DHCPNAK. Found the hard way
by benno who didn't want to wait 127 seconds.

Due to another bug dhcpleased would have exit through a fatal() in the
frontend process if he had waited long enough for a Rebooting -> Init
transition because we didn't deconfigure our IP address and thus
didn't close our UDP socket. Upon configuring a new IP address we would
open a new UDP socket send it to the frontend which would then fatal()
due to an unexpected fd passed in.

Aproporiate timings are rather underspecified in RFC 2131. Instead of
doing an exponential backoff up to 64 in the "Rebooting" and
"Requesting" state only go up to 2 for a total of 3 packets and total
timeout of 3 seconds before going into "Init" state and sending a
DHCPDISCOVER.

To prevent the fatal() in the frontend process we reshuffle the state
transition into the "Init" state and deconfigure the IP when
appropriate.

Revision 1.6 / (download) - annotate - [select for diffs], Mon Mar 1 15:56:31 2021 UTC (3 years, 3 months ago) by florian
Branch: MAIN
Changes since 1.5: +75 -1 lines
Diff to previous 1.5 (colored)

Log adding and deleting of IP addresses as well as nameservers.
deraadt@ pointed out that dhcpleased is too quiet.

Revision 1.5 / (download) - annotate - [select for diffs], Mon Mar 1 15:56:00 2021 UTC (3 years, 3 months ago) by florian
Branch: MAIN
Changes since 1.4: +1 -6 lines
Diff to previous 1.4 (colored)

We really must handle all possible enumeration values in
state_transition() and iface_timeout(). Let the compiler help us by
emitting a warning when we missed one (-Wswitch).
Reminded by jsg who pointed out that gcc is quite confused and thinks
there is an out of bounds access in if_state_name[] in the default
case. There is not, if_state_name[] and enum if_state have to be kept
in sync.
(Note that -Wswitch is not a silver bullet, it just happens to work
here.)

Revision 1.4 / (download) - annotate - [select for diffs], Mon Mar 1 15:54:49 2021 UTC (3 years, 3 months ago) by florian
Branch: MAIN
Changes since 1.3: +15 -23 lines
Diff to previous 1.3 (colored)

Let send_rdns_withdraw and send_deconfigure_interface clean up after
themselves. This way the iface object is in a consistent state.
For consistency we should also withdraw rdns first, then deconfigure
the interface.
Lastly make sure we parse the lease file on a down -> up transition if
we had a lease before and it had expired while the interface was in
down state. Otherwise we'd send a dhcpdiscover requesting any IP
address while we really should send a dhcprequest asking for our
previous IP back.

Revision 1.3 / (download) - annotate - [select for diffs], Sun Feb 28 15:26:26 2021 UTC (3 years, 3 months ago) by florian
Branch: MAIN
Changes since 1.2: +19 -16 lines
Diff to previous 1.2 (colored)

Introduce #defines for exponential backoff, explain where they come
from and explain why we are a bit more agressive during startup.
While here make the math a bit easier on the eyes.

Revision 1.2 / (download) - annotate - [select for diffs], Sat Feb 27 10:07:41 2021 UTC (3 years, 3 months ago) by florian
Branch: MAIN
Changes since 1.1: +19 -24 lines
Diff to previous 1.1 (colored)

Read the lease file into a statically sized buffer and pass it over to
the engine process for parsing instead of passing an fd.
Let's us tighten the engine's pledge back down to "stdio".

Revision 1.1 / (download) - annotate - [select for diffs], Fri Feb 26 16:16:37 2021 UTC (3 years, 3 months ago) by florian
Branch: MAIN

Import dhcpleased(8) - a dhcp daemon to acquire IPv4 address leases
from servers.

dhcpleased(8) follows the well known three process design of all our
privsep daemons. It uses pledge(2) and unveil(2) to restrict access
further. In particular the "engine" process, responsible for parsing
of untrusted data, is pledge'd "stdio". It cannot access the outside
world nor the filesystem at all.

Like slaacd(8) for IPv6 it will be always running and acquire addresses
for all interface with the autoconf4 flag set.
The flag can be set by "ifconfig $if inet autoconf" or by adding
"inet autoconf" to /etc/hostname.if. An existing "dhcp" line should
be removed.

Various iterations tested by deraadt@
The hardest part, finding a name, was handled by jmatthew@ & otto@

"get to it :)" deraadt@

This form allows you to request diff's between any two revisions of a file. You may select a symbolic revision name using the selection box or you may type in a numeric name using the type-in text box.