diff options
author | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-03-04 16:15:00 +0100 |
---|---|---|
committer | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-03-04 16:15:00 +0100 |
commit | 2bf7a76d864804c38c47426b40a00b71f00136d7 (patch) | |
tree | fcbd8b5de20e521c3a564fb1d09dac7ffdab05e5 | |
parent | fa16ecc5202a8ba9e329e2f25c67106beb517d2f (diff) |
support DHCPRELEASE
-rw-r--r-- | src/lease.rs | 17 | ||||
-rw-r--r-- | src/main.rs | 26 |
2 files changed, 43 insertions, 0 deletions
diff --git a/src/lease.rs b/src/lease.rs index 779ec31..0369a72 100644 --- a/src/lease.rs +++ b/src/lease.rs @@ -28,6 +28,7 @@ pub trait LeaseManager { fn leases(&self) -> Box<dyn Iterator<Item = Lease>>; fn request(&mut self, address: Ipv4Addr, client_id: &[u8]) -> bool; fn lease_time(&self) -> Duration; + fn release(&mut self, client_id: &[u8]) -> Box<dyn Iterator<Item = Ipv4Addr>>; fn all_addresses(&self) -> Vec<Ipv4Addr> { let range = self.range(); @@ -169,4 +170,20 @@ impl LeaseManager for LeaseDummyManager { fn lease_time(&self) -> Duration { Duration::from_secs(300) } + + fn release(&mut self, client_id: &[u8]) -> Box<dyn Iterator<Item = Ipv4Addr>> { + let mut released = Vec::new(); + + self.leases + .clone() + .into_iter() + .enumerate() + .filter(|(_, lease)| lease.client_id == client_id) + .for_each(|(i, lease)| { + self.leases.remove(i); + released.push(lease.address); + }); + + Box::new(released.into_iter()) + } } diff --git a/src/main.rs b/src/main.rs index 4d58082..ac2f8ff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -225,6 +225,32 @@ fn handle_request( } } } + MessageType::Release => { + let client_id = match opts + .get(OptionCode::ClientIdentifier) + .ok_or(anyhow!("no client id"))? + { + DhcpOption::ClientIdentifier(id) => id, + _ => bail!("expected ClientIdentifier"), + }; + + let mut lease_mgr = lease_mgr.lock().unwrap(); + let released: Vec<String> = lease_mgr + .release(client_id) + .map(|addr| addr.to_string()) + .collect(); + + let released_pretty = released.join(", "); + + let cid = client_id + .iter() + .map(|octet| format!("{:x}", octet)) + .reduce(|acc, octet| acc + &octet) + .ok_or(anyhow!("zero-length client id"))?; + + println!("releasing {} for client ID {}", released_pretty, cid); + Ok(()) + } _ => Err(anyhow!("invalid message type {:?}", msg_type,)), } } |