diff --git a/Cargo.lock b/Cargo.lock index 15be459..c8642fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1086,6 +1086,7 @@ name = "nzr-api" version = "0.1.0" dependencies = [ "figment", + "log", "serde", "tarpc", "tokio", diff --git a/api/Cargo.toml b/api/Cargo.toml index 38700d1..415b6a2 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -11,4 +11,5 @@ serde = { version = "1", features = ["derive"] } tarpc = { version = "0.31", features = ["tokio1", "unix"] } tokio = { version = "1.0", features = ["macros"] } uuid = "1.2.2" -trust-dns-proto = { version = "0.22.0", features = ["serde-config"] } \ No newline at end of file +trust-dns-proto = { version = "0.22.0", features = ["serde-config"] } +log = "0.4.17" \ No newline at end of file diff --git a/api/src/net/cidr.rs b/api/src/net/cidr.rs index 1c49638..d6b71a6 100644 --- a/api/src/net/cidr.rs +++ b/api/src/net/cidr.rs @@ -162,6 +162,11 @@ impl CidrV4 { /// This method is not affected by the object's host address. pub fn make_ip(&self, host_bits: u32) -> Result { if host_bits > !self.netmask { + log::error!( + "Host bits too large ({:032b} vs {:032b})", + !self.netmask, + host_bits + ); Err(Error::HostBitsTooLarge) } else { Ok((host_bits | u32::from(self.network().addr)).into()) diff --git a/nzrd/src/ctrl/net.rs b/nzrd/src/ctrl/net.rs index 38d4d00..57eeab6 100644 --- a/nzrd/src/ctrl/net.rs +++ b/nzrd/src/ctrl/net.rs @@ -140,14 +140,18 @@ impl Entity { ) -> Result, Box> { let tree = self.db.open_tree(self.lease_tree())?; let max_lease = match tree.last()? { - Some(lease) => u32::from_be_bytes(lease.0[..4].try_into().unwrap()), + Some(lease) => { + // XXX: this is overkill, but a lazy hack for now + u32::from_be_bytes(lease.0[..4].try_into().unwrap()) + & !u32::from(self.model.network.netmask()) + } None => self.model.start_bytes(), }; let new_ip = self .model .network .make_ip(max_lease + 1) - .map_err(|_| SubnetError::SubnetFull)?; + .map_err(SubnetError::BadHost)?; let lease_data = Lease { subnet: String::from_utf8_lossy(&self.key).to_string(), ipv4_addr: CidrV4::new(new_ip, self.model.network.cidr()),