Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix DHCPv4 panic when T1 < T2 < lease duration is not respected #1029

Merged
merged 1 commit into from
Jan 3, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions src/socket/dhcpv4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,8 @@ impl<'a> Socket<'a> {
// Times T1 and T2 are configurable by the server through
// options. T1 defaults to (0.5 * duration_of_lease). T2
// defaults to (0.875 * duration_of_lease).
// When receiving T1 and T2, they must be in the order:
// T1 < T2 < lease_duration
let (renew_duration, rebind_duration) = match (
dhcp_repr
.renew_duration
Expand All @@ -510,26 +512,36 @@ impl<'a> Socket<'a> {
.rebind_duration
.map(|d| Duration::from_secs(d as u64)),
) {
(Some(renew_duration), Some(rebind_duration)) => (renew_duration, rebind_duration),
(None, None) => (lease_duration / 2, lease_duration * 7 / 8),
(Some(renew_duration), Some(rebind_duration))
if renew_duration < rebind_duration && rebind_duration < lease_duration =>
{
(renew_duration, rebind_duration)
}
// RFC 2131 does not say what to do if only one value is
// provided, so:

// If only T1 is provided, set T2 to be 0.75 through the gap
// between T1 and the duration of the lease. If T1 is set to
// the default (0.5 * duration_of_lease), then T2 will also
// be set to the default (0.875 * duration_of_lease).
(Some(renew_duration), None) => (
(Some(renew_duration), None) if renew_duration < lease_duration => (
renew_duration,
renew_duration + (lease_duration - renew_duration) * 3 / 4,
),

// If only T2 is provided, then T1 will be set to be
// whichever is smaller of the default (0.5 *
// duration_of_lease) or T2.
(None, Some(rebind_duration)) => {
(None, Some(rebind_duration)) if rebind_duration < lease_duration => {
((lease_duration / 2).min(rebind_duration), rebind_duration)
}

// Use the defaults if the following order is not met:
// T1 < T2 < lease_duration
(_, _) => {
net_debug!("using default T1 and T2 values since the provided values are invalid");
(lease_duration / 2, lease_duration * 7 / 8)
}
};
let renew_at = now + renew_duration;
let rebind_at = now + rebind_duration;
Expand Down
Loading