From 2a3aff9b8003ee68d08db8c407a177bdc8868bf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=B6rjesson?= Date: Sat, 10 May 2025 22:16:59 +0200 Subject: [PATCH 1/3] Reuse server DHCPOFFER transaction id in DHCPREQUEST --- src/socket/dhcpv4.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/socket/dhcpv4.rs b/src/socket/dhcpv4.rs index 7d8c920ad..51d7a9fe4 100644 --- a/src/socket/dhcpv4.rs +++ b/src/socket/dhcpv4.rs @@ -72,6 +72,8 @@ struct RequestState { server: ServerInfo, /// IP address that we're trying to request. requested_ip: Ipv4Address, + /// Transaction ID from server's `Offer` message + offer_transaction_id: u32, } #[derive(Debug)] @@ -379,6 +381,7 @@ impl<'a> Socket<'a> { identifier: server_identifier, }, requested_ip: dhcp_repr.your_ip, // use the offered ip + offer_transaction_id: dhcp_repr.transaction_id, }); } (ClientState::Requesting(state), DhcpMessageType::Ack) => { @@ -652,6 +655,7 @@ impl<'a> Socket<'a> { dhcp_repr.message_type = DhcpMessageType::Request; dhcp_repr.requested_ip = Some(state.requested_ip); dhcp_repr.server_identifier = Some(state.server.identifier); + dhcp_repr.transaction_id = state.offer_transaction_id; net_debug!( "DHCP send request to {}: {:?}", @@ -666,7 +670,7 @@ impl<'a> Socket<'a> { + (self.retry_config.initial_request_timeout << (state.retry as u32 / 2)); state.retry += 1; - self.transaction_id = next_transaction_id; + self.transaction_id = state.offer_transaction_id; Ok(()) } ClientState::Renewing(state) => { From b7045405f57a355fbeb15c742f645b5699365edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=B6rjesson?= Date: Thu, 28 Aug 2025 21:31:18 +0200 Subject: [PATCH 2/3] Remove redundant offer_transaction_id --- src/socket/dhcpv4.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/socket/dhcpv4.rs b/src/socket/dhcpv4.rs index 51d7a9fe4..c5fef8b2e 100644 --- a/src/socket/dhcpv4.rs +++ b/src/socket/dhcpv4.rs @@ -72,8 +72,6 @@ struct RequestState { server: ServerInfo, /// IP address that we're trying to request. requested_ip: Ipv4Address, - /// Transaction ID from server's `Offer` message - offer_transaction_id: u32, } #[derive(Debug)] @@ -381,7 +379,6 @@ impl<'a> Socket<'a> { identifier: server_identifier, }, requested_ip: dhcp_repr.your_ip, // use the offered ip - offer_transaction_id: dhcp_repr.transaction_id, }); } (ClientState::Requesting(state), DhcpMessageType::Ack) => { @@ -655,7 +652,7 @@ impl<'a> Socket<'a> { dhcp_repr.message_type = DhcpMessageType::Request; dhcp_repr.requested_ip = Some(state.requested_ip); dhcp_repr.server_identifier = Some(state.server.identifier); - dhcp_repr.transaction_id = state.offer_transaction_id; + dhcp_repr.transaction_id = self.transaction_id; net_debug!( "DHCP send request to {}: {:?}", @@ -670,7 +667,6 @@ impl<'a> Socket<'a> { + (self.retry_config.initial_request_timeout << (state.retry as u32 / 2)); state.retry += 1; - self.transaction_id = state.offer_transaction_id; Ok(()) } ClientState::Renewing(state) => { From 48d10eb4a49abe2908a7910314640282588d7654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=B6rjesson?= Date: Fri, 29 Aug 2025 16:45:32 +0200 Subject: [PATCH 3/3] Avoid generating unused xid:s --- src/socket/dhcpv4.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/socket/dhcpv4.rs b/src/socket/dhcpv4.rs index c5fef8b2e..6b7e717d5 100644 --- a/src/socket/dhcpv4.rs +++ b/src/socket/dhcpv4.rs @@ -574,13 +574,9 @@ impl<'a> Socket<'a> { // 0x0f * 4 = 60 bytes. const MAX_IPV4_HEADER_LEN: usize = 60; - // We don't directly modify self.transaction_id because sending the packet - // may fail. We only want to update state after successfully sending. - let next_transaction_id = Self::random_transaction_id(cx); - let mut dhcp_repr = DhcpRepr { message_type: DhcpMessageType::Discover, - transaction_id: next_transaction_id, + transaction_id: self.transaction_id, secs: 0, client_hardware_address: ethernet_addr, client_ip: Ipv4Address::UNSPECIFIED, @@ -624,6 +620,9 @@ impl<'a> Socket<'a> { return Ok(()); } + let next_transaction_id = Self::random_transaction_id(cx); + dhcp_repr.transaction_id = next_transaction_id; + // send packet net_debug!( "DHCP send DISCOVER to {}: {:?}", @@ -652,7 +651,6 @@ impl<'a> Socket<'a> { dhcp_repr.message_type = DhcpMessageType::Request; dhcp_repr.requested_ip = Some(state.requested_ip); dhcp_repr.server_identifier = Some(state.server.identifier); - dhcp_repr.transaction_id = self.transaction_id; net_debug!( "DHCP send request to {}: {:?}", @@ -692,6 +690,9 @@ impl<'a> Socket<'a> { dhcp_repr.message_type = DhcpMessageType::Request; dhcp_repr.client_ip = state.config.address.address(); + let next_transaction_id = Self::random_transaction_id(cx); + dhcp_repr.transaction_id = next_transaction_id; + net_debug!("DHCP send renew to {}: {:?}", ipv4_repr.dst_addr, dhcp_repr); ipv4_repr.payload_len = udp_repr.header_len() + dhcp_repr.buffer_len(); emit(cx, (ipv4_repr, udp_repr, dhcp_repr))?;