diff options
-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,)), } } |